From 9222a52d91e4c15f77ffdb5fe268d005a0750ae2 Mon Sep 17 00:00:00 2001 From: landaiqing Date: Sat, 20 Sep 2025 19:18:33 +0800 Subject: [PATCH] :sparkles: Modified sql prettier plugin --- frontend/package-lock.json | 112 +- frontend/package.json | 2 - .../common/prettier/plugins/clang/index.ts | 81 +- .../prettier/plugins/clang/scripts/build.sh | 44 + .../prettier/plugins/clang/scripts/cli.patch | 95 ++ .../plugins/clang/scripts/gen_patch.sh | 27 + .../prettier/plugins/dart/extra/.npmignore | 3 - .../prettier/plugins/dart/extra/dart_fmt.d.ts | 32 - .../prettier/plugins/dart/extra/dart_fmt.js | 84 -- .../plugins/dart/extra/dart_fmt_node.js | 10 - .../plugins/dart/extra/dart_fmt_vite.js | 8 - .../src/common/prettier/plugins/dart/index.ts | 18 +- .../common/prettier/plugins/dart/lib/build.sh | 5 + .../prettier/plugins/dart/scripts/build.sh | 7 - .../prettier/plugins/dart/scripts/package.mjs | 16 - .../prettier/plugins/dart/scripts/patch.mjs | 13 - .../prettier/plugins/lua/extra/.npmignore | 2 - .../plugins/lua/extra/lua_fmt_node.js | 10 - .../plugins/lua/extra/lua_fmt_vite.js | 8 - .../prettier/plugins/lua/scripts/package.mjs | 39 - .../plugins/lua/{scripts => src}/build.sh | 5 - .../common/prettier/plugins/sql/detect.mjs | 1180 ----------------- .../src/common/prettier/plugins/sql/index.ts | 140 ++ .../common/prettier/plugins/sql/languages.js | 30 - .../src/common/prettier/plugins/sql/sql.d.ts | 40 - .../src/common/prettier/plugins/sql/sql.mjs | 459 ------- .../common/prettier/plugins/sql/sql_fmt.d.ts | 58 + .../common/prettier/plugins/sql/sql_fmt.js | 524 ++++++++ .../prettier/plugins/sql/sql_fmt_bg.wasm | Bin 0 -> 195086 bytes .../prettier/plugins/sql/sql_fmt_bg.wasm.d.ts | 9 + .../web_fmt_node.js => sql/sql_fmt_node.js} | 6 +- .../prettier/plugins/sql/sql_fmt_vite.js | 8 + .../common/prettier/plugins/sql/src/build.sh | 3 + .../common/prettier/plugins/sql/src/lib.rs | 97 ++ .../plugins/web/json_fmt/extra/.npmignore | 2 - .../web/json_fmt/extra/json_fmt_node.js | 10 - .../web/json_fmt/extra/json_fmt_vite.js | 8 - .../plugins/web/json_fmt/scripts/package.mjs | 39 - .../web/json_fmt/{scripts => src}/build.sh | 5 - .../plugins/web/web_fmt/extra/.npmignore | 2 - .../plugins/web/web_fmt/extra/web_fmt_vite.js | 8 - .../plugins/web/web_fmt/scripts/package.mjs | 39 - .../web/web_fmt/{scripts => src}/build.sh | 5 - .../codeblock/lang-parser/languages.ts | 17 +- 44 files changed, 1099 insertions(+), 2211 deletions(-) create mode 100644 frontend/src/common/prettier/plugins/clang/scripts/build.sh create mode 100644 frontend/src/common/prettier/plugins/clang/scripts/cli.patch create mode 100644 frontend/src/common/prettier/plugins/clang/scripts/gen_patch.sh delete mode 100644 frontend/src/common/prettier/plugins/dart/extra/.npmignore delete mode 100644 frontend/src/common/prettier/plugins/dart/extra/dart_fmt.d.ts delete mode 100644 frontend/src/common/prettier/plugins/dart/extra/dart_fmt.js delete mode 100644 frontend/src/common/prettier/plugins/dart/extra/dart_fmt_node.js delete mode 100644 frontend/src/common/prettier/plugins/dart/extra/dart_fmt_vite.js create mode 100644 frontend/src/common/prettier/plugins/dart/lib/build.sh delete mode 100644 frontend/src/common/prettier/plugins/dart/scripts/build.sh delete mode 100644 frontend/src/common/prettier/plugins/dart/scripts/package.mjs delete mode 100644 frontend/src/common/prettier/plugins/dart/scripts/patch.mjs delete mode 100644 frontend/src/common/prettier/plugins/lua/extra/.npmignore delete mode 100644 frontend/src/common/prettier/plugins/lua/extra/lua_fmt_node.js delete mode 100644 frontend/src/common/prettier/plugins/lua/extra/lua_fmt_vite.js delete mode 100644 frontend/src/common/prettier/plugins/lua/scripts/package.mjs rename frontend/src/common/prettier/plugins/lua/{scripts => src}/build.sh (57%) delete mode 100644 frontend/src/common/prettier/plugins/sql/detect.mjs create mode 100644 frontend/src/common/prettier/plugins/sql/index.ts delete mode 100644 frontend/src/common/prettier/plugins/sql/languages.js delete mode 100644 frontend/src/common/prettier/plugins/sql/sql.d.ts delete mode 100644 frontend/src/common/prettier/plugins/sql/sql.mjs create mode 100644 frontend/src/common/prettier/plugins/sql/sql_fmt.d.ts create mode 100644 frontend/src/common/prettier/plugins/sql/sql_fmt.js create mode 100644 frontend/src/common/prettier/plugins/sql/sql_fmt_bg.wasm create mode 100644 frontend/src/common/prettier/plugins/sql/sql_fmt_bg.wasm.d.ts rename frontend/src/common/prettier/plugins/{web/web_fmt/extra/web_fmt_node.js => sql/sql_fmt_node.js} (53%) create mode 100644 frontend/src/common/prettier/plugins/sql/sql_fmt_vite.js create mode 100644 frontend/src/common/prettier/plugins/sql/src/build.sh create mode 100644 frontend/src/common/prettier/plugins/sql/src/lib.rs delete mode 100644 frontend/src/common/prettier/plugins/web/json_fmt/extra/.npmignore delete mode 100644 frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_node.js delete mode 100644 frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_vite.js delete mode 100644 frontend/src/common/prettier/plugins/web/json_fmt/scripts/package.mjs rename frontend/src/common/prettier/plugins/web/json_fmt/{scripts => src}/build.sh (57%) delete mode 100644 frontend/src/common/prettier/plugins/web/web_fmt/extra/.npmignore delete mode 100644 frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_vite.js delete mode 100644 frontend/src/common/prettier/plugins/web/web_fmt/scripts/package.mjs rename frontend/src/common/prettier/plugins/web/web_fmt/{scripts => src}/build.sh (57%) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 4aafb22..aec72af 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -55,7 +55,6 @@ "jinx-rust": "^0.1.6", "jsox": "^1.2.123", "linguist-languages": "^9.0.0", - "node-sql-parser": "^5.3.12", "php-parser": "^3.2.5", "pinia": "^3.0.3", "pinia-plugin-persistedstate": "^4.5.0", @@ -63,7 +62,6 @@ "remarkable": "^2.0.1", "sass": "^1.92.1", "sh-syntax": "^0.5.8", - "sql-formatter": "^15.6.9", "vue": "^3.5.21", "vue-i18n": "^11.1.12", "vue-pick-colors": "^1.8.0", @@ -2279,12 +2277,6 @@ "undici-types": "~7.10.0" } }, - "node_modules/@types/pegjs": { - "version": "0.10.6", - "resolved": "https://registry.npmmirror.com/@types/pegjs/-/pegjs-0.10.6.tgz", - "integrity": "sha512-eLYXDbZWXh2uxf+w8sXS8d6KSoXTswfps6fvCUuVAGN8eRpfe7h9eSRydxiSJvo9Bf+GzifsDOr9TMQlmJdmkw==", - "license": "MIT" - }, "node_modules/@types/remarkable": { "version": "2.0.8", "resolved": "https://registry.npmmirror.com/@types/remarkable/-/remarkable-2.0.8.tgz", @@ -2894,6 +2886,7 @@ "version": "2.0.1", "resolved": "https://registry.npmmirror.com/argparse/-/argparse-2.0.1.tgz", "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, "license": "Python-2.0" }, "node_modules/asn1.js": { @@ -2982,15 +2975,6 @@ ], "license": "MIT" }, - "node_modules/big-integer": { - "version": "1.6.52", - "resolved": "https://registry.npmmirror.com/big-integer/-/big-integer-1.6.52.tgz", - "integrity": "sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg==", - "license": "Unlicense", - "engines": { - "node": ">=0.6" - } - }, "node_modules/binary-extensions": { "version": "2.3.0", "resolved": "https://registry.npmmirror.com/binary-extensions/-/binary-extensions-2.3.0.tgz", @@ -3507,12 +3491,6 @@ "url": "https://jaywcjlove.github.io/#/sponsor" } }, - "node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmmirror.com/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "license": "MIT" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz", @@ -3852,12 +3830,6 @@ "dev": true, "license": "MIT" }, - "node_modules/discontinuous-range": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz", - "integrity": "sha512-c68LpLbO+7kP/b1Hr1qs8/BJ09F5khZGTxqxZuhzxpmwJKOgRFHJWIb9/KmqnqHhLdO55aOxFH/EGBvUQbL/RQ==", - "license": "MIT" - }, "node_modules/domain-browser": { "version": "4.22.0", "resolved": "https://registry.npmmirror.com/domain-browser/-/domain-browser-4.22.0.tgz", @@ -5340,12 +5312,6 @@ "pathe": "^2.0.1" } }, - "node_modules/moo": { - "version": "0.5.2", - "resolved": "https://registry.npmmirror.com/moo/-/moo-0.5.2.tgz", - "integrity": "sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==", - "license": "BSD-3-Clause" - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", @@ -5395,28 +5361,6 @@ "dev": true, "license": "MIT" }, - "node_modules/nearley": { - "version": "2.20.1", - "resolved": "https://registry.npmmirror.com/nearley/-/nearley-2.20.1.tgz", - "integrity": "sha512-+Mc8UaAebFzgV+KpI5n7DasuuQCHA89dmwm7JXw3TV43ukfNQ9DnBH3Mdb2g/I4Fdxc26pwimBWvjIw0UAILSQ==", - "license": "MIT", - "dependencies": { - "commander": "^2.19.0", - "moo": "^0.5.0", - "railroad-diagrams": "^1.0.0", - "randexp": "0.4.6" - }, - "bin": { - "nearley-railroad": "bin/nearley-railroad.js", - "nearley-test": "bin/nearley-test.js", - "nearley-unparse": "bin/nearley-unparse.js", - "nearleyc": "bin/nearleyc.js" - }, - "funding": { - "type": "individual", - "url": "https://nearley.js.org/#give-to-nearley" - } - }, "node_modules/node-addon-api": { "version": "7.1.1", "resolved": "https://registry.npmmirror.com/node-addon-api/-/node-addon-api-7.1.1.tgz", @@ -5432,19 +5376,6 @@ "optional": true, "peer": true }, - "node_modules/node-sql-parser": { - "version": "5.3.12", - "resolved": "https://registry.npmmirror.com/node-sql-parser/-/node-sql-parser-5.3.12.tgz", - "integrity": "sha512-GQBwA2e44qjbK0MzFwh5bNYefniV6cKT4KfjNDpuh/2EWipUEK1BCMc//moSidp8EF6fHB/EqJwUH9GCh9MAPg==", - "license": "Apache-2.0", - "dependencies": { - "@types/pegjs": "^0.10.0", - "big-integer": "^1.6.48" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/node-stdlib-browser": { "version": "1.3.1", "resolved": "https://registry.npmmirror.com/node-stdlib-browser/-/node-stdlib-browser-1.3.1.tgz", @@ -6103,25 +6034,6 @@ ], "license": "MIT" }, - "node_modules/railroad-diagrams": { - "version": "1.0.0", - "resolved": "https://registry.npmmirror.com/railroad-diagrams/-/railroad-diagrams-1.0.0.tgz", - "integrity": "sha512-cz93DjNeLY0idrCNOH6PviZGRN9GJhsdm9hpn1YCS879fj4W+x5IFJhhkRZcwVgMmFF7R82UA/7Oh+R8lLZg6A==", - "license": "CC0-1.0" - }, - "node_modules/randexp": { - "version": "0.4.6", - "resolved": "https://registry.npmmirror.com/randexp/-/randexp-0.4.6.tgz", - "integrity": "sha512-80WNmd9DA0tmZrw9qQa62GPPWfuXJknrmVmLcxvq4uZBdYqb1wYoKTmnlGUchvVWe0XiLupYkBoXVOxz3C8DYQ==", - "license": "MIT", - "dependencies": { - "discontinuous-range": "1.0.0", - "ret": "~0.1.10" - }, - "engines": { - "node": ">=0.12" - } - }, "node_modules/randombytes": { "version": "2.1.0", "resolved": "https://registry.npmmirror.com/randombytes/-/randombytes-2.1.0.tgz", @@ -6255,15 +6167,6 @@ "node": ">=4" } }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmmirror.com/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "license": "MIT", - "engines": { - "node": ">=0.12" - } - }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmmirror.com/reusify/-/reusify-1.1.0.tgz", @@ -6674,19 +6577,6 @@ "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "license": "BSD-3-Clause" }, - "node_modules/sql-formatter": { - "version": "15.6.9", - "resolved": "https://registry.npmmirror.com/sql-formatter/-/sql-formatter-15.6.9.tgz", - "integrity": "sha512-r9VKnkRfKW7jbhTgytwbM+JqmFclQYN9L58Z3UTktuy9V1f1Y+rGK3t70Truh2wIOJzvZkzobAQ2PwGjjXsr6Q==", - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1", - "nearley": "^2.20.1" - }, - "bin": { - "sql-formatter": "bin/sql-formatter-cli.cjs" - } - }, "node_modules/std-env": { "version": "3.9.0", "resolved": "https://registry.npmmirror.com/std-env/-/std-env-3.9.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index ac9cd5e..a6d130d 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -59,7 +59,6 @@ "jinx-rust": "^0.1.6", "jsox": "^1.2.123", "linguist-languages": "^9.0.0", - "node-sql-parser": "^5.3.12", "php-parser": "^3.2.5", "pinia": "^3.0.3", "pinia-plugin-persistedstate": "^4.5.0", @@ -67,7 +66,6 @@ "remarkable": "^2.0.1", "sass": "^1.92.1", "sh-syntax": "^0.5.8", - "sql-formatter": "^15.6.9", "vue": "^3.5.21", "vue-i18n": "^11.1.12", "vue-pick-colors": "^1.8.0", diff --git a/frontend/src/common/prettier/plugins/clang/index.ts b/frontend/src/common/prettier/plugins/clang/index.ts index 8ceb1cd..16361e0 100644 --- a/frontend/src/common/prettier/plugins/clang/index.ts +++ b/frontend/src/common/prettier/plugins/clang/index.ts @@ -1,23 +1,31 @@ /** - * Prettier Plugin for C/C++ formatting using clang-format WebAssembly + * Prettier Plugin for C/C++/C#/Java/Protobuf formatting using clang-format WebAssembly * - * This plugin provides support for formatting C/C++ files using the clang-format WASM implementation. - * It supports various C/C++ file extensions and common clang-format styles. + * This plugin provides support for formatting multiple languages using the clang-format WASM implementation. + * Supported languages: + * - C / C++ + * - Objective-C / Objective-C++ + * - C# + * - Java + * - Protocol Buffer (Protobuf) + * + * It supports various file extensions and common clang-format styles. */ import type { Plugin, Parser, Printer } from 'prettier'; // Import the clang-format WASM module import clangFormatInit, { format } from './clang-format-vite.js'; -const parserName = 'clang'; +const parserName = 'clang-format'; // Language configuration const languages = [ { name: 'C', aliases: ['c'], - parsers: [parserName], + parsers: ['c'], extensions: ['.c', '.h'], + filenames: ['*.c', '*.h'], aceMode: 'c_cpp', tmScope: 'source.c', linguistLanguageId: 50, @@ -26,8 +34,9 @@ const languages = [ { name: 'C++', aliases: ['cpp', 'cxx', 'cc'], - parsers: [parserName], + parsers: ['cpp'], extensions: ['.cpp', '.cxx', '.cc', '.hpp', '.hxx', '.hh', '.C', '.H'], + filenames: ['*.cpp', '*.cxx', '*.cc', '*.hpp', '*.hxx', '*.hh', '*.C', '*.H'], aceMode: 'c_cpp', tmScope: 'source.cpp', linguistLanguageId: 43, @@ -36,12 +45,57 @@ const languages = [ { name: 'Objective-C', aliases: ['objc', 'objectivec'], - parsers: [parserName], - extensions: ['.m', '.mm'], + parsers: ['objective-c'], + extensions: ['.m'], + filenames: ['*.m'], aceMode: 'objectivec', tmScope: 'source.objc', linguistLanguageId: 259, vscodeLanguageIds: ['objective-c'] + }, + { + name: 'Objective-C++', + aliases: ['objcpp', 'objectivecpp'], + parsers: ['objective-cpp'], + extensions: ['.mm'], + filenames: ['*.mm'], + aceMode: 'objectivec', + tmScope: 'source.objcpp', + linguistLanguageId: 260, + vscodeLanguageIds: ['objective-cpp'] + }, + { + name: 'C#', + aliases: ['csharp', 'cs'], + parsers: ['cs'], + extensions: ['.cs'], + filenames: ['*.cs'], + aceMode: 'csharp', + tmScope: 'source.cs', + linguistLanguageId: 42, + vscodeLanguageIds: ['csharp'] + }, + { + name: 'Java', + aliases: ['java'], + parsers: ['java'], + extensions: ['.java'], + filenames: ['*.java'], + aceMode: 'java', + tmScope: 'source.java', + linguistLanguageId: 181, + vscodeLanguageIds: ['java'] + }, + { + name: 'Protocol Buffer', + aliases: ['protobuf', 'proto'], + parsers: ['proto'], + extensions: ['.proto'], + filenames: ['*.proto'], + aceMode: 'protobuf', + tmScope: 'source.proto', + linguistLanguageId: 297, + vscodeLanguageIds: ['proto'] } ]; @@ -85,7 +139,7 @@ const clangPrinter: Printer = { const style = getClangStyle(options); // Format using clang-format (synchronous call) - const formatted = format(text, undefined, style); + const formatted = format(text, options.filename, style); return formatted.trim(); } catch (error) { @@ -129,6 +183,13 @@ const options = { { value: 'Microsoft', description: "Microsoft's style guide" }, { value: 'GNU', description: 'GNU coding standards' } ] + }, + filename: { + // since: '0.1.0', + category: 'Config', + type: 'string', + default: undefined, + description: 'Custom filename to use for web_fmt processing (affects language detection)', } }; @@ -141,7 +202,7 @@ const clangPlugin: Plugin = { printers: { [parserName]: clangPrinter, }, - options, + ...options, }; // Initialize WASM module when plugin loads diff --git a/frontend/src/common/prettier/plugins/clang/scripts/build.sh b/frontend/src/common/prettier/plugins/clang/scripts/build.sh new file mode 100644 index 0000000..0014eb5 --- /dev/null +++ b/frontend/src/common/prettier/plugins/clang/scripts/build.sh @@ -0,0 +1,44 @@ +set -Eeo pipefail + +cd $(dirname $0)/.. +project_root=$(pwd) + +rm -rf pkg +mkdir -p pkg build +cd build + +export CC=$(which clang) +export CXX=$(which clang++) + +emcmake cmake -G Ninja .. +ninja clang-format-wasm + +cd $project_root + +if [[ ! -z "${WASM_OPT}" ]]; then + wasm-opt -Os build/clang-format-esm.wasm -o build/clang-format-esm-Os.wasm + wasm-opt -Oz build/clang-format-esm.wasm -o build/clang-format-esm-Oz.wasm +fi + +SMALLEST_WASM=$(ls -Sr build/clang-format-e*.wasm | head -1) + +cp $SMALLEST_WASM pkg/clang-format.wasm +cat src/template.js build/clang-format-esm.js >pkg/clang-format.js + +# add shebang +echo '#!/usr/bin/env node' | cat - ./build/clang-format-cli.js >./pkg/clang-format-cli.cjs +cp ./build/clang-format-cli.wasm ./pkg/ + +cp ./src/clang-format.d.ts src/clang-format-*.js ./pkg/ +cp ./package.json LICENSE README.md .npmignore ./pkg/ + +# copy git-clang-format and clang-format-diff.py +cp ./build/_deps/llvm_project-src/clang/tools/clang-format/git-clang-format ./pkg/ +cp ./build/_deps/llvm_project-src/clang/tools/clang-format/clang-format-diff.py ./pkg/ + +ls -lh ./pkg + +./scripts/package.mjs ./package.json + +# make sure repo is clean +# git diff --exit-code diff --git a/frontend/src/common/prettier/plugins/clang/scripts/cli.patch b/frontend/src/common/prettier/plugins/clang/scripts/cli.patch new file mode 100644 index 0000000..aa60a50 --- /dev/null +++ b/frontend/src/common/prettier/plugins/clang/scripts/cli.patch @@ -0,0 +1,95 @@ +diff --git a/src/cli.cc b/src/cli.cc +index 2861005..69ec009 100644 +--- a/src/cli.cc ++++ b/src/cli.cc +@@ -12,7 +12,7 @@ + /// + //===----------------------------------------------------------------------===// + +-#include "../../lib/Format/MatchFilePath.h" ++#include "clang/../../lib/Format/MatchFilePath.h" + #include "clang/Basic/Diagnostic.h" + #include "clang/Basic/DiagnosticOptions.h" + #include "clang/Basic/FileManager.h" +@@ -27,6 +27,8 @@ + #include "llvm/Support/Process.h" + #include + ++#include "CustomFileSystem.h" ++ + using namespace llvm; + using clang::tooling::Replacements; + +@@ -448,9 +450,12 @@ static bool format(StringRef FileName, bool ErrorOnIncompleteFormat = false) { + return true; + } + ++ auto RealFS = vfs::getRealFileSystem(); ++ auto CustomFS = new vfs::CustomFileSystem(RealFS); ++ IntrusiveRefCntPtr CustomFSPtr(CustomFS); + Expected FormatStyle = + getStyle(Style, AssumedFileName, FallbackStyle, Code->getBuffer(), +- nullptr, WNoErrorList.isSet(WNoError::Unknown)); ++ CustomFSPtr.get(), WNoErrorList.isSet(WNoError::Unknown)); + if (!FormatStyle) { + llvm::errs() << toString(FormatStyle.takeError()) << "\n"; + return true; +@@ -571,10 +576,15 @@ static int dumpConfig() { + } + Code = std::move(CodeOrErr.get()); + } ++ ++ auto RealFS = vfs::getRealFileSystem(); ++ auto CustomFS = new vfs::CustomFileSystem(RealFS); ++ IntrusiveRefCntPtr CustomFSPtr(CustomFS); ++ + Expected FormatStyle = clang::format::getStyle( + Style, + FileNames.empty() || FileNames[0] == "-" ? AssumeFileName : FileNames[0], +- FallbackStyle, Code ? Code->getBuffer() : ""); ++ FallbackStyle, Code ? Code->getBuffer() : "", CustomFSPtr.get()); + if (!FormatStyle) { + llvm::errs() << toString(FormatStyle.takeError()) << "\n"; + return 1; +@@ -607,24 +617,26 @@ static bool isIgnored(StringRef FilePath) { + String Path; + String AbsPath{FilePath}; + ++ auto PathStyle = vfs::getPathStyle(); ++ + using namespace llvm::sys::path; +- make_absolute(AbsPath); +- remove_dots(AbsPath, /*remove_dot_dot=*/true); ++ vfs::make_absolute(AbsPath); ++ remove_dots(AbsPath, /*remove_dot_dot=*/true, PathStyle); + +- if (StringRef Dir{parent_path(AbsPath)}; PrevDir != Dir) { ++ if (StringRef Dir{parent_path(AbsPath, PathStyle)}; PrevDir != Dir) { + PrevDir = Dir; + + for (;;) { + Path = Dir; +- append(Path, ".clang-format-ignore"); ++ append(Path, PathStyle, ".clang-format-ignore"); + if (is_regular_file(Path)) + break; +- Dir = parent_path(Dir); ++ Dir = parent_path(Dir, PathStyle); + if (Dir.empty()) + return false; + } + +- IgnoreDir = convert_to_slash(Dir); ++ IgnoreDir = convert_to_slash(Dir, PathStyle); + + std::ifstream IgnoreFile{Path.c_str()}; + if (!IgnoreFile.good()) +@@ -644,7 +656,7 @@ static bool isIgnored(StringRef FilePath) { + if (IgnoreDir.empty()) + return false; + +- const auto Pathname{convert_to_slash(AbsPath)}; ++ const auto Pathname{convert_to_slash(AbsPath, PathStyle)}; + for (const auto &Pat : Patterns) { + const bool IsNegated = Pat[0] == '!'; + StringRef Pattern{Pat}; diff --git a/frontend/src/common/prettier/plugins/clang/scripts/gen_patch.sh b/frontend/src/common/prettier/plugins/clang/scripts/gen_patch.sh new file mode 100644 index 0000000..d929543 --- /dev/null +++ b/frontend/src/common/prettier/plugins/clang/scripts/gen_patch.sh @@ -0,0 +1,27 @@ +current_dir=$(pwd) +tmp_dir=$(mktemp -d) + +cd $tmp_dir + +git init + +cp $current_dir/build/_deps/llvm_project-src/clang/tools/clang-format/ClangFormat.cpp ./cli.cc + +git add -f . +git commit -m "init" + +cp $current_dir/src/cli.cc ./cli.cc + +git add -f . +git diff \ + --cached \ + --no-color \ + --ignore-space-at-eol \ + --no-ext-diff \ + --src-prefix=a/src/ \ + --dst-prefix=b/src/ \ + >$current_dir/scripts/cli.patch || true + +rm -rf $tmp_dir + + diff --git a/frontend/src/common/prettier/plugins/dart/extra/.npmignore b/frontend/src/common/prettier/plugins/dart/extra/.npmignore deleted file mode 100644 index 826d6ab..0000000 --- a/frontend/src/common/prettier/plugins/dart/extra/.npmignore +++ /dev/null @@ -1,3 +0,0 @@ -*.tgz -*.unopt.wasm -jsr.jsonc \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt.d.ts b/frontend/src/common/prettier/plugins/dart/extra/dart_fmt.d.ts deleted file mode 100644 index 5850092..0000000 --- a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt.d.ts +++ /dev/null @@ -1,32 +0,0 @@ -export function format(input: string, filename: string, config?: LayoutConfig): string; - -interface LayoutConfig { - line_width?: number; - line_ending?: "lf" | "crlf"; - language_version?: string; -} - -export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; - -export type InitOutput = unknown; - -// export type SyncInitInput = BufferSource | WebAssembly.Module; -// /** -// * Instantiates the given `module`, which can either be bytes or -// * a precompiled `WebAssembly.Module`. -// * -// * @param {SyncInitInput} module -// * -// * @returns {InitOutput} -// */ -// export function initSync(module: SyncInitInput): InitOutput; - -/** -* If `module_or_path` is {RequestInfo} or {URL}, makes a request and -* for everything else, calls `WebAssembly.instantiate` directly. -* -* @param {InitInput | Promise} module_or_path -* -* @returns {Promise} -*/ -export default function init(module_or_path?: InitInput | Promise): Promise; diff --git a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt.js b/frontend/src/common/prettier/plugins/dart/extra/dart_fmt.js deleted file mode 100644 index 57bf65b..0000000 --- a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt.js +++ /dev/null @@ -1,84 +0,0 @@ -import { format as dart_fmt, instantiate, invoke } from "./dart_fmt.mjs"; - -let wasm; - -function get_imports() {} -function init_memory() {} - -function normalize(module) { - if (!(module instanceof WebAssembly.Module)) { - return new WebAssembly.Module(module); - } - return module; -} - -export default async function (input) { - if (wasm !== undefined) return wasm; - - if (typeof input === "undefined") { - input = new URL("dart_fmt.wasm", import.meta.url); - } - const imports = get_imports(); - - if ( - typeof input === "string" || - (typeof Request === "function" && input instanceof Request) || - (typeof URL === "function" && input instanceof URL) - ) { - input = fetch(input); - } - - init_memory(imports); - - wasm = await load(await input) - .then(normalize) - .then(instantiate); - - invoke(wasm); - - return wasm; -} - -async function load(module) { - if (typeof Response === "function" && module instanceof Response) { - if ("compileStreaming" in WebAssembly) { - try { - return await WebAssembly.compileStreaming(module); - } catch (e) { - if (module.headers.get("Content-Type") != "application/wasm") { - console.warn( - "`WebAssembly.compileStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", - e, - ); - } else { - throw e; - } - } - } - - return module.arrayBuffer(); - } - - return module; -} - -export function format(source, filename = "stdin.dart", config = {}) { - const options = { lineEnding: "\n" }; - if (config.line_width) { - options.pageWidth = config.line_width; - } - if (options.line_ending === "crlf") { - options.lineEnding = "\r\n"; - } - if(options.language_version) { - options.languageVersion = options.language_version; - } - - const result = dart_fmt(source, filename, JSON.stringify(options)); - const err = result[0] === "x"; - const output = result.slice(1); - if (err) { - throw new Error(output); - } - return output; -} diff --git a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt_node.js b/frontend/src/common/prettier/plugins/dart/extra/dart_fmt_node.js deleted file mode 100644 index 1d809ae..0000000 --- a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt_node.js +++ /dev/null @@ -1,10 +0,0 @@ -import fs from "node:fs/promises"; -import initAsync from "./dart_fmt.js"; - -const wasm = new URL("./dart_fmt.wasm", import.meta.url); - -export default function __wbg_init(init = fs.readFile(wasm)) { - return initAsync(init); -} - -export * from "./dart_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt_vite.js b/frontend/src/common/prettier/plugins/dart/extra/dart_fmt_vite.js deleted file mode 100644 index 070451c..0000000 --- a/frontend/src/common/prettier/plugins/dart/extra/dart_fmt_vite.js +++ /dev/null @@ -1,8 +0,0 @@ -import initAsync from "./dart_fmt.js"; -import wasm from "./dart_fmt.wasm?url"; - -export default function __wbg_init(input = wasm) { - return initAsync(input); -} - -export * from "./dart_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/dart/index.ts b/frontend/src/common/prettier/plugins/dart/index.ts index a8625f7..040984d 100644 --- a/frontend/src/common/prettier/plugins/dart/index.ts +++ b/frontend/src/common/prettier/plugins/dart/index.ts @@ -62,11 +62,10 @@ const dartPrinter: Printer = { } const text = (path as any).getValue ? (path as any).getValue() : path.node; - const filename = getDartFilename(options.filepath); const config = getDartConfig(options); // Format using dart_fmt (synchronous call) - const formatted = format(text, filename, config); + const formatted = format(text, undefined, config); return formatted.trim(); } catch (error) { @@ -77,21 +76,6 @@ const dartPrinter: Printer = { }, }; -// Helper function to get appropriate filename for dart_fmt -function getDartFilename(filepath?: string): string { - if (!filepath) { - return 'stdin.dart'; - } - - const filename = filepath.split(/[/\\]/).pop() || 'main.dart'; - - // Ensure .dart extension - if (!filename.endsWith('.dart')) { - return 'main.dart'; - } - - return filename; -} // Helper function to create Dart config from Prettier options function getDartConfig(options: any): any { diff --git a/frontend/src/common/prettier/plugins/dart/lib/build.sh b/frontend/src/common/prettier/plugins/dart/lib/build.sh new file mode 100644 index 0000000..07da5f8 --- /dev/null +++ b/frontend/src/common/prettier/plugins/dart/lib/build.sh @@ -0,0 +1,5 @@ +cd $(dirname $0)/.. + +dart compile wasm ./lib/binding.dart -o ./build/dart_fmt.wasm + + diff --git a/frontend/src/common/prettier/plugins/dart/scripts/build.sh b/frontend/src/common/prettier/plugins/dart/scripts/build.sh deleted file mode 100644 index 86a8ce9..0000000 --- a/frontend/src/common/prettier/plugins/dart/scripts/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -cd $(dirname $0)/.. - -dart compile wasm ./lib/binding.dart -o ./build/dart_fmt.wasm -cp -LR ./extra/. ./build/ - -./scripts/patch.mjs ./build/dart_fmt.mjs -./scripts/package.mjs ./package.json diff --git a/frontend/src/common/prettier/plugins/dart/scripts/package.mjs b/frontend/src/common/prettier/plugins/dart/scripts/package.mjs deleted file mode 100644 index 210f62d..0000000 --- a/frontend/src/common/prettier/plugins/dart/scripts/package.mjs +++ /dev/null @@ -1,16 +0,0 @@ -#!/usr/bin/env node -import process from "node:process"; -import path from "node:path"; -import fs from "node:fs"; - -const pkg_path = path.resolve(process.cwd(), process.argv[2]); -const pkg_text = fs.readFileSync(pkg_path, { encoding: "utf-8" }); -const pkg_json = JSON.parse(pkg_text); - -// JSR - -const jsr_path = path.resolve(pkg_path, "..", "build", "jsr.jsonc"); -pkg_json.name = "@fmt/dart-fmt"; -pkg_json.exports = "./dart_fmt.js"; -pkg_json.exclude = ["!../build", "*.tgz", ".npmignore"]; -fs.writeFileSync(jsr_path, JSON.stringify(pkg_json, null, 4)); diff --git a/frontend/src/common/prettier/plugins/dart/scripts/patch.mjs b/frontend/src/common/prettier/plugins/dart/scripts/patch.mjs deleted file mode 100644 index 39c50a2..0000000 --- a/frontend/src/common/prettier/plugins/dart/scripts/patch.mjs +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env node -import process from "node:process"; -import path from "node:path"; -import fs from "node:fs"; - -const file_path = path.resolve(process.cwd(), process.argv[2]); -let file_text = fs.readFileSync(file_path, { encoding: "utf-8" }); - -file_text = file_text.replace(`"length": (s) => s.length`, '"length": (s) => s?.length||0'); -file_text = file_text.replace('globalThis.format', 'format'); -file_text += "\nexport let format;"; - -fs.writeFileSync(file_path, file_text); \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/lua/extra/.npmignore b/frontend/src/common/prettier/plugins/lua/extra/.npmignore deleted file mode 100644 index 1ee7305..0000000 --- a/frontend/src/common/prettier/plugins/lua/extra/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -*.tgz -jsr.jsonc \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/lua/extra/lua_fmt_node.js b/frontend/src/common/prettier/plugins/lua/extra/lua_fmt_node.js deleted file mode 100644 index 8828ec5..0000000 --- a/frontend/src/common/prettier/plugins/lua/extra/lua_fmt_node.js +++ /dev/null @@ -1,10 +0,0 @@ -import fs from "node:fs/promises"; -import initAsync from "./lua_fmt.js"; - -const wasm = new URL("./lua_fmt_bg.wasm", import.meta.url); - -export default function __wbg_init(init = { module_or_path: fs.readFile(wasm) }) { - return initAsync(init); -} - -export * from "./lua_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/lua/extra/lua_fmt_vite.js b/frontend/src/common/prettier/plugins/lua/extra/lua_fmt_vite.js deleted file mode 100644 index 770a144..0000000 --- a/frontend/src/common/prettier/plugins/lua/extra/lua_fmt_vite.js +++ /dev/null @@ -1,8 +0,0 @@ -import initAsync from "./lua_fmt.js"; -import wasm from "./lua_fmt_bg.wasm?url"; - -export default function __wbg_init(input = { module_or_path: wasm }) { - return initAsync(input); -} - -export * from "./lua_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/lua/scripts/package.mjs b/frontend/src/common/prettier/plugins/lua/scripts/package.mjs deleted file mode 100644 index d1452f8..0000000 --- a/frontend/src/common/prettier/plugins/lua/scripts/package.mjs +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env node -import process from "node:process"; -import path from "node:path"; -import fs from "node:fs"; - -const pkg_path = path.resolve(process.cwd(), process.argv[2]); -const pkg_text = fs.readFileSync(pkg_path, { encoding: "utf-8" }); -const pkg_json = JSON.parse(pkg_text); - -delete pkg_json.files; - -pkg_json.main = pkg_json.module; -pkg_json.type = "module"; -pkg_json.publishConfig = { - access: "public", -}; -pkg_json.exports = { - ".": { - types: "./lua_fmt.d.ts", - node: "./lua_fmt_node.js", - default: "./lua_fmt.js", - }, - "./vite": { - types: "./lua_fmt.d.ts", - default: "./lua_fmt_vite.js", - }, - "./package.json": "./package.json", - "./*": "./*", -}; - -fs.writeFileSync(pkg_path, JSON.stringify(pkg_json, null, 4)); - -// JSR - -const jsr_path = path.resolve(pkg_path, "..", "jsr.jsonc"); -pkg_json.name = "@fmt/lua-fmt"; -pkg_json.exports = "./lua_fmt.js"; -pkg_json.exclude = ["!**", "*.tgz"]; -fs.writeFileSync(jsr_path, JSON.stringify(pkg_json, null, 4)); diff --git a/frontend/src/common/prettier/plugins/lua/scripts/build.sh b/frontend/src/common/prettier/plugins/lua/src/build.sh similarity index 57% rename from frontend/src/common/prettier/plugins/lua/scripts/build.sh rename to frontend/src/common/prettier/plugins/lua/src/build.sh index de4317b..00af102 100644 --- a/frontend/src/common/prettier/plugins/lua/scripts/build.sh +++ b/frontend/src/common/prettier/plugins/lua/src/build.sh @@ -4,8 +4,3 @@ crates_dir=$(pwd) cd ../.. wasm-pack build --target=web --scope=wasm-fmt crates/lua_fmt -cd $crates_dir - -cp -R ./extra/. ./pkg/ - -./scripts/package.mjs ./pkg/package.json diff --git a/frontend/src/common/prettier/plugins/sql/detect.mjs b/frontend/src/common/prettier/plugins/sql/detect.mjs deleted file mode 100644 index 297e306..0000000 --- a/frontend/src/common/prettier/plugins/sql/detect.mjs +++ /dev/null @@ -1,1180 +0,0 @@ -// SQL方言特征检测规则 -const dialectPatterns = { - mysql: [ - /\bAUTO_INCREMENT\b/i, - /\bENGINE\s*=/i, - /\bCHARSET\s*=/i, - /\bCOLLATE\s*=/i, - /\bLIMIT\s+\d+\s*OFFSET\s+\d+/i, - /\bUNSIGNED\b/i, - /\bTINYINT\b/i, - /\bMEDIUMINT\b/i, - /\bBIGINT\b/i, - /\bTEXT\b/i, - /\bLONGTEXT\b/i, - /\bMEDIUMTEXT\b/i, - /\bTINYTEXT\b/i, - /\bENUM\s*\(/i, - /\bSET\s*\(/i, - /\bIF\s*\(/i, - /\bIFNULL\s*\(/i, - /\bCONCAT\s*\(/i, - /\bGROUP_CONCAT\s*\(/i, - /\bDATE_FORMAT\s*\(/i, - /\bSTR_TO_DATE\s*\(/i, - /\bUNIX_TIMESTAMP\s*\(/i, - /\bFROM_UNIXTIME\s*\(/i, - /\bINSERT\s+IGNORE\b/i, - /\bREPLACE\s+INTO\b/i, - /\bON\s+DUPLICATE\s+KEY\s+UPDATE\b/i - ], - - postgresql: [ - /\bSERIAL\b/i, - /\bBIGSERIAL\b/i, - /\bSMALLSERIAL\b/i, - /\bBOOLEAN\b/i, - /\bTEXT\[\]/i, - /\bINTEGER\[\]/i, - /\bJSONB\b/i, - /\bUUID\b/i, - /\bINET\b/i, - /\bCIDR\b/i, - /\bMACaddr\b/i, - /\bTSVECTOR\b/i, - /\bTSQUERY\b/i, - /\bPOINT\b/i, - /\bLINE\b/i, - /\bLSEG\b/i, - /\bBOX\b/i, - /\bPATH\b/i, - /\bPOLYGON\b/i, - /\bCIRCLE\b/i, - /\bLIMIT\s+\d+\s+OFFSET\s+\d+/i, - /\bRETURNING\b/i, - /\bON\s+CONFLICT\b/i, - /\bDO\s+NOTHING\b/i, - /\bDO\s+UPDATE\s+SET\b/i, - /\bFETCH\s+FIRST\b/i, - /\bFETCH\s+NEXT\b/i, - /\bROWS\s+ONLY\b/i, - /\bWITH\s+RECURSIVE\b/i, - /\bARRAY\s*\[/i, - /\bUNNEST\s*\(/i, - /\bSTRING_AGG\s*\(/i, - /\bEXTRACT\s*\(/i, - /\bGENERATE_SERIES\s*\(/i, - /\bCOALESCE\s*\(/i, - /\bNULLIF\s*\(/i, - /\bAGE\s*\(/i, - /\bNOW\s*\(\s*\)/i, - /\bCURRENT_TIMESTAMP\b/i, - /\bCURRENT_DATE\b/i, - /\bCURRENT_TIME\b/i, - /\bINTERVAL\s+'/i, - /\bREGEXP_REPLACE\s*\(/i, - /\bREGEXP_SPLIT_TO_ARRAY\s*\(/i, - /\b\$\$[^$]*\$\$/i, - /\bCREATE\s+EXTENSION\b/i, - /\bCREATE\s+OR\s+REPLACE\s+FUNCTION\b/i, - /\bCREATE\s+OR\s+REPLACE\s+VIEW\b/i, - /\bPLPGSQL\b/i, - /\bTABLESPACE\b/i, - /\bSCHEMA\b/i - ], - - sqlite: [ - /\bPRAGMA\b/i, - /\bAUTOINCREMENT\b/i, - /\bWITHOUT\s+ROWID\b/i, - /\bSTRICT\b/i, - /\bIF\s+NOT\s+EXISTS\b/i, - /\bREPLACE\b/i, - /\bVACUUM\b/i, - /\bREINDEX\b/i, - /\bANALYZE\b/i, - /\bATTACH\s+DATABASE\b/i, - /\bDETACH\s+DATABASE\b/i, - /\bTEMP\b/i, - /\bTEMPORARY\b/i, - /\bBEGIN\s+IMMEDIATE\b/i, - /\bBEGIN\s+EXCLUSIVE\b/i, - /\bEXPLAIN\s+QUERY\s+PLAN\b/i, - /\bRANDOM\s*\(\s*\)/i, - /\bLENGTH\s*\(/i, - /\bSUBSTR\s*\(/i, - /\bREPLACE\s*\(/i, - /\bTRIM\s*\(/i, - /\bLTRIM\s*\(/i, - /\bRTRIM\s*\(/i, - /\bUPPER\s*\(/i, - /\bLOWER\s*\(/i, - /\bINSTR\s*\(/i, - /\bROUND\s*\(/i, - /\bABS\s*\(/i, - /\bMAX\s*\(/i, - /\bMIN\s*\(/i, - /\bDATE\s*\(/i, - /\bTIME\s*\(/i, - /\bDATETIME\s*\(/i, - /\bJULIANDAY\s*\(/i, - /\bSTRFTIME\s*\(/i, - /\bGLOB\s*\(/i, - /\bLIKE\s*\(/i, - /\bCAST\s*\(/i, - /\bTYPEOF\s*\(/i - ], - - transactsql: [ - /\bIDENTITY\s*\(/i, - /\bUNIQUEIDENTIFIER\b/i, - /\bNVARCHAR\b/i, - /\bNTEXT\b/i, - /\bNUMERIC\b/i, - /\bSMALLDATETIME\b/i, - /\bDATETIME2\b/i, - /\bDATETIMEOFFSET\b/i, - /\bTIME\b/i, - /\bIMAGE\b/i, - /\bMONEY\b/i, - /\bSMALLMONEY\b/i, - /\bSQL_VARIANT\b/i, - /\bTABLE\b/i, - /\bXML\b/i, - /\bGEOMETRY\b/i, - /\bGEOGRAPHY\b/i, - /\bTOP\s+\d+/i, - /\bPERCENT\b/i, - /\bWITH\s+TIES\b/i, - /\bOFFSET\s+\d+\s+ROWS/i, - /\bFETCH\s+NEXT\s+\d+\s+ROWS\s+ONLY/i, - /\bISNULL\s*\(/i, - /\bCONVERT\s*\(/i, - /\bCAST\s*\(/i, - /\bDATEDIFF\s*\(/i, - /\bDATEADD\s*\(/i, - /\bDATEPART\s*\(/i, - /\bGETDATE\s*\(\s*\)/i, - /\bGETUTCDATE\s*\(\s*\)/i, - /\bSYSDATETIME\s*\(\s*\)/i, - /\bSYSUTCDATETIME\s*\(\s*\)/i, - /\bCURRENT_TIMESTAMP\b/i, - /\bLEN\s*\(/i, - /\bLEFT\s*\(/i, - /\bRIGHT\s*\(/i, - /\bCHARINDEX\s*\(/i, - /\bPATINDEX\s*\(/i, - /\bSTUFF\s*\(/i, - /\bREVERSE\s*\(/i, - /\bREPLICATE\s*\(/i, - /\bSPACE\s*\(/i, - /\bSTR\s*\(/i, - /\bFORMAT\s*\(/i, - /\bPARSENAME\s*\(/i, - /\bQUOTENAME\s*\(/i, - /\bMERGE\b/i, - /\bWHEN\s+MATCHED\b/i, - /\bWHEN\s+NOT\s+MATCHED\b/i, - /\bUSING\b/i, - /\bOUTPUT\b/i, - /\bINSERTED\b/i, - /\bDELETED\b/i, - /\bTRUNCATE\s+TABLE\b/i, - /\bEXEC\b/i, - /\bEXECUTE\b/i, - /\bSP_EXECUTESQL\b/i, - /\bBEGIN\s+TRAN\b/i, - /\bCOMMIT\s+TRAN\b/i, - /\bROLLBACK\s+TRAN\b/i, - /\bSAVE\s+TRAN\b/i, - /\bTRY\b/i, - /\bCATCH\b/i, - /\bTHROW\b/i, - /\bRAISERROR\b/i, - /\bPRINT\b/i, - /\bSET\s+NOCOUNT\s+ON\b/i, - /\bSET\s+ANSI_NULLS\s+ON\b/i, - /\bSET\s+QUOTED_IDENTIFIER\s+ON\b/i, - /\bWITH\s+\(\s*NOLOCK\s*\)/i, - /\bROW_NUMBER\s*\(\s*\)\s+OVER\s*\(/i, - /\bRANK\s*\(\s*\)\s+OVER\s*\(/i, - /\bDENSE_RANK\s*\(\s*\)\s+OVER\s*\(/i, - /\bNTILE\s*\(/i, - /\bLAG\s*\(/i, - /\bLEAD\s*\(/i, - /\bFIRST_VALUE\s*\(/i, - /\bLAST_VALUE\s*\(/i, - /\bCTE\b/i, - /\bPIVOT\b/i, - /\bUNPIVOT\b/i, - /\bAPPLY\b/i, - /\bOUTER\s+APPLY\b/i, - /\bCROSS\s+APPLY\b/i - ], - - bigquery: [ - /\bSTRUCT\s*/i, - /\bBEFORE\s*\(\s*TIMESTAMP\s*=>/i, - /\bQUALIFY\b/i, - /\bMINUS\b/i, - /\bCONCAT\s*\(/i, - /\bCONCAT_WS\s*\(/i, - /\bSPLIT\s*\(/i, - /\bSPLIT_PART\s*\(/i, - /\bSTARTSWITH\s*\(/i, - /\bENDSWITH\s*\(/i, - /\bCONTAINS\s*\(/i, - /\bTRY_CAST\s*\(/i, - /\bTRY_TO_NUMBER\s*\(/i, - /\bTRY_TO_DECIMAL\s*\(/i, - /\bTRY_TO_DATE\s*\(/i, - /\bTRY_TO_TIME\s*\(/i, - /\bTRY_TO_TIMESTAMP\s*\(/i, - /\bTRY_TO_BINARY\s*\(/i, - /\bPARSE_JSON\s*\(/i, - /\bPARSE_XML\s*\(/i, - /\bTRY_PARSE_JSON\s*\(/i, - /\bCHECK_JSON\s*\(/i, - /\bCHECK_XML\s*\(/i, - /\bSTRIP_NULL_VALUE\s*\(/i, - /\bOBJECT_CONSTRUCT\s*\(/i, - /\bOBJECT_CONSTRUCT_KEEP_NULL\s*\(/i, - /\bOBJECT_DELETE\s*\(/i, - /\bOBJECT_INSERT\s*\(/i, - /\bOBJECT_PICK\s*\(/i, - /\bARRAY_CONSTRUCT\s*\(/i, - /\bARRAY_CONSTRUCT_COMPACT\s*\(/i, - /\bARRAY_APPEND\s*\(/i, - /\bARRAY_CAT\s*\(/i, - /\bARRAY_COMPACT\s*\(/i, - /\bARRAY_CONTAINS\s*\(/i, - /\bARRAY_DISTINCT\s*\(/i, - /\bARRAY_EXCEPT\s*\(/i, - /\bARRAY_FLATTEN\s*\(/i, - /\bARRAY_GENERATE_RANGE\s*\(/i, - /\bARRAY_INSERT\s*\(/i, - /\bARRAY_INTERSECTION\s*\(/i, - /\bARRAY_POSITION\s*\(/i, - /\bARRAY_PREPEND\s*\(/i, - /\bARRAY_REMOVE\s*\(/i, - /\bARRAY_REMOVE_AT\s*\(/i, - /\bARRAY_SIZE\s*\(/i, - /\bARRAY_SLICE\s*\(/i, - /\bARRAY_SORT\s*\(/i, - /\bARRAY_TO_STRING\s*\(/i, - /\bARRAY_UNION\s*\(/i, - /\bARRAY_UNIQUE_AGG\s*\(/i, - /\bGET\s*\(/i, - /\bGET_PATH\s*\(/i, - /\bFLATTEN\s*\(/i, - /\bCURRENT_AVAILABLE_ROLES\s*\(\s*\)/i, - /\bCURRENT_CLIENT\s*\(\s*\)/i, - /\bCURRENT_DATABASE\s*\(\s*\)/i, - /\bCURRENT_REGION\s*\(\s*\)/i, - /\bCURRENT_ROLE\s*\(\s*\)/i, - /\bCURRENT_SCHEMA\s*\(\s*\)/i, - /\bCURRENT_SCHEMAS\s*\(\s*\)/i, - /\bCURRENT_SESSION\s*\(\s*\)/i, - /\bCURRENT_STATEMENT\s*\(\s*\)/i, - /\bCURRENT_TIME\s*\(\s*\)/i, - /\bCURRENT_TIMESTAMP\s*\(\s*\)/i, - /\bCURRENT_TRANSACTION\s*\(\s*\)/i, - /\bCURRENT_USER\s*\(\s*\)/i, - /\bCURRENT_VERSION\s*\(\s*\)/i, - /\bCURRENT_WAREHOUSE\s*\(\s*\)/i, - /\bLOCALTIME\s*\(\s*\)/i, - /\bLOCALTIMESTAMP\s*\(\s*\)/i, - /\bSYSDATE\s*\(\s*\)/i, - /\bGETDATE\s*\(\s*\)/i, - /\bLAST_DAY\s*\(/i, - /\bNEXT_DAY\s*\(/i, - /\bPREVIOUS_DAY\s*\(/i, - /\bDATE_FROM_PARTS\s*\(/i, - /\bTIME_FROM_PARTS\s*\(/i, - /\bTIMESTAMP_FROM_PARTS\s*\(/i, - /\bDAYNAME\s*\(/i, - /\bMONTHNAME\s*\(/i, - /\bQUARTER\s*\(/i, - /\bYEAROFWEEK\s*\(/i, - /\bYEAROFWEEKISO\s*\(/i, - /\bWEEKOFYEAR\s*\(/i, - /\bWEEKISO\s*\(/i, - /\bDAYOFWEEK\s*\(/i, - /\bDAYOFWEEKISO\s*\(/i, - /\bDAYOFYEAR\s*\(/i, - /\bHOUR\s*\(/i, - /\bMINUTE\s*\(/i, - /\bSECOND\s*\(/i, - /\bNANOSECOND\s*\(/i, - /\bEPOCH_SECOND\s*\(/i, - /\bEPOCH_MILLISECOND\s*\(/i, - /\bEPOCH_MICROSECOND\s*\(/i, - /\bEPOCH_NANOSECOND\s*\(/i, - /\bTIMEZONE_HOUR\s*\(/i, - /\bTIMEZONE_MINUTE\s*\(/i, - /\bISO_WEEK_START\s*\(/i, - /\bISO_WEEK_END\s*\(/i, - /\bWEEK_START\s*\(/i, - /\bWEEK_END\s*\(/i, - /\bISO_YEAR_START\s*\(/i, - /\bISO_YEAR_END\s*\(/i, - /\bYEAR_START\s*\(/i, - /\bYEAR_END\s*\(/i, - /\bCONVERT_TIMEZONE\s*\(/i, - /\bIFF\s*\(/i, - /\bZEROIFNULL\s*\(/i, - /\bNULLIFZERO\s*\(/i, - /\bEQUAL_NULL\s*\(/i, - /\bBOOLAND\s*\(/i, - /\bBOOLOR\s*\(/i, - /\bBOOLXOR\s*\(/i, - /\bBOOLNOT\s*\(/i, - /\bMODE\s*\(/i, - /\bUNIFORM\s*\(/i, - /\bNORMAL\s*\(/i, - /\bSEQ1\s*\(\s*\)/i, - /\bSEQ2\s*\(\s*\)/i, - /\bSEQ4\s*\(\s*\)/i, - /\bSEQ8\s*\(\s*\)/i, - /\bUUID_STRING\s*\(\s*\)/i, - /\bRANDOM\s*\(\s*\)/i, - /\bRRANDOM\s*\(/i, - /\bZIPF\s*\(/i, - /\bHASH\s*\(/i, - /\bSHA1\s*\(/i, - /\bSHA1_HEX\s*\(/i, - /\bSHA1_BINARY\s*\(/i, - /\bSHA2\s*\(/i, - /\bSHA2_HEX\s*\(/i, - /\bSHA2_BINARY\s*\(/i, - /\bMD5\s*\(/i, - /\bMD5_HEX\s*\(/i, - /\bMD5_BINARY\s*\(/i, - /\bMD5_NUMBER\s*\(/i, - /\bMD5_NUMBER_LOWER64\s*\(/i, - /\bMD5_NUMBER_UPPER64\s*\(/i, - /\bBASE64_ENCODE\s*\(/i, - /\bBASE64_DECODE_STRING\s*\(/i, - /\bBASE64_DECODE_BINARY\s*\(/i, - /\bHEX_ENCODE\s*\(/i, - /\bHEX_DECODE_STRING\s*\(/i, - /\bHEX_DECODE_BINARY\s*\(/i, - /\bTRY_BASE64_DECODE_STRING\s*\(/i, - /\bTRY_BASE64_DECODE_BINARY\s*\(/i, - /\bTRY_HEX_DECODE_STRING\s*\(/i, - /\bTRY_HEX_DECODE_BINARY\s*\(/i, - /\bCOMPRESS\s*\(/i, - /\bDECOMPRESS_STRING\s*\(/i, - /\bDECOMPRESS_BINARY\s*\(/i - ], - - mariadb: [ - // MariaDB specific features (extends MySQL) - /\bSEQUENCE\b/i, - /\bROLE\b/i, - /\bCOLUMN_CHECK\s*\(/i, - /\bCOLUMN_GET\s*\(/i, - /\bCOLUMN_JSON\s*\(/i, - /\bDYNAMIC_COLUMN_\w+\s*\(/i, - /\bJSON_ARRAY\s*\(/i, - /\bJSON_ARRAYAGG\s*\(/i, - /\bJSON_OBJECT\s*\(/i, - /\bJSON_OBJECTAGG\s*\(/i, - /\bJSON_EXTRACT\s*\(/i, - /\bJSON_UNQUOTE\s*\(/i, - /\bJSON_VALID\s*\(/i, - /\bGIS\b/i, - /\bSPIDER\b/i, - /\bCONNECT\s+ENGINE\b/i, - /\bFEDERATEDX\b/i, - /\bCONNECTION\s*=/i, - /\bVIRTUAL\s+COLUMN\b/i, - /\bSTORED\s+COLUMN\b/i, - /\bGENERATED\s+ALWAYS\b/i, - /\bAUTO_INCREMENT\b/i, - /\bENGINE\s*=/i, - /\bCHARSET\s*=/i, - /\bCOLLATE\s*=/i - ], - - db2: [ - // IBM DB2 specific features - /\bIDENTITY\s*\(\s*START\s+WITH\b/i, - /\bGENERATED\s+ALWAYS\b/i, - /\bGENERATED\s+BY\s+DEFAULT\b/i, - /\bDECLARE\s+GLOBAL\s+TEMPORARY\s+TABLE\b/i, - /\bFINAL\s+TABLE\b/i, - /\bNEW\s+TABLE\b/i, - /\bOLD\s+TABLE\b/i, - /\bDECFLOAT\b/i, - /\bBIGINT\b/i, - /\bSMALLINT\b/i, - /\bREAL\b/i, - /\bDOUBLE\b/i, - /\bGRAPHIC\s*\(/i, - /\bVARGRAPHIC\s*\(/i, - /\bDBCLOB\s*\(/i, - /\bXML\b/i, - /\bROWID\b/i, - /\bDATE\b/i, - /\bTIME\b/i, - /\bTIMESTAMP\b/i, - /\bVALUES\s+NEXTVAL\s+FOR\b/i, - /\bVALUES\s+PREVVAL\s+FOR\b/i, - /\bFETCH\s+FIRST\s+\d+\s+ROWS\s+ONLY\b/i, - /\bFETCH\s+NEXT\s+\d+\s+ROWS\s+ONLY\b/i, - /\bROW\s+CHANGE\s+TIMESTAMP\b/i, - /\bROW\s+BEGIN\b/i, - /\bROW\s+END\b/i, - /\bSYSTEM_TIME\b/i, - /\bBUSINESS_TIME\b/i, - /\bVERSIONING\b/i, - /\bWITH\s+ORDINALITY\b/i, - /\bLATERAL\b/i, - /\bOVER\s*\(\s*PARTITION\s+BY\b/i, - /\bRANKING\b/i, - /\bAGGREGATION\b/i, - /\bNUMBERING\b/i - ], - - db2i: [ - // IBM DB2 for i specific features (AS/400) - /\bAS\/400\b/i, - /\biSeries\b/i, - /\bSYSTEM\s+i\b/i, - /\bQSYS\b/i, - /\bQTEMP\b/i, - /\bRCDFMT\b/i, - /\bDATA\s+AREA\b/i, - /\bJOURNAL\b/i, - /\bJRNL\b/i, - /\bLIBRARY\b/i, - /\bSCHEMA\b/i, - /\bCOLLECTION\b/i, - /\bMEMBER\b/i, - /\bFILE\b/i, - /\bRECORD\b/i, - /\bFIELD\b/i, - /\bKEYWORD\b/i, - /\bVALUES\b/i, - /\bRUNSQLSTM\b/i, - /\bSTRSQL\b/i, - /\bINTERACTIVE\s+SQL\b/i, - /\bSQL\s+REQUEST\b/i, - /\bSQL\s+PACKAGE\b/i, - /\bBINDING\b/i, - /\bACCESS\s+PLAN\b/i, - /\bOPTIMIZATION\b/i, - /\bSTAT_VIEW\b/i, - /\bMQT\b/i, - /\bMATERIALIZED\s+QUERY\s+TABLE\b/i, - /\bREFRESH\s+DEFERRED\b/i, - /\bREFRESH\s+IMMEDIATE\b/i, - /\bENABLE\s+QUERY\s+OPTIMIZATION\b/i, - /\bDISABLE\s+QUERY\s+OPTIMIZATION\b/i - ], - - hive: [ - // Apache Hive specific features - /\bPARTITIONED\s+BY\b/i, - /\bCLUSTERED\s+BY\b/i, - /\bSORTED\s+BY\b/i, - /\bINTO\s+\d+\s+BUCKETS\b/i, - /\bSTORED\s+AS\s+ORC\b/i, - /\bSTORED\s+AS\s+PARQUET\b/i, - /\bSTORED\s+AS\s+AVRO\b/i, - /\bSTORED\s+AS\s+RCFILE\b/i, - /\bSTORED\s+AS\s+SEQUENCEFILE\b/i, - /\bSTORED\s+AS\s+TEXTFILE\b/i, - /\bROW\s+FORMAT\s+SERDE\b/i, - /\bINPUTFORMAT\b/i, - /\bOUTPUTFORMAT\b/i, - /\bLOCATION\s+'/i, - /\bTBLPROPERTIES\s*\(/i, - /\bSERDEPROPERTIES\s*\(/i, - /\bADD\s+JAR\b/i, - /\bADD\s+FILE\b/i, - /\bADD\s+ARCHIVE\b/i, - /\bTRANSFORM\b/i, - /\bUSING\s+'/i, - /\bAS\s+\(/i, - /\bLATERAL\s+VIEW\b/i, - /\bEXPLODE\s*\(/i, - /\bPOSEXPLODE\s*\(/i, - /\bINLINE\s*\(/i, - /\bSTACK\s*\(/i, - /\bJSON_TUPLE\s*\(/i, - /\bPARSE_URL\s*\(/i, - /\bPARSE_URL_TUPLE\s*\(/i, - /\bXPATH\s*\(/i, - /\bXPATH_STRING\s*\(/i, - /\bXPATH_BOOLEAN\s*\(/i, - /\bXPATH_NUMBER\s*\(/i, - /\bXPATH_DOUBLE\s*\(/i, - /\bXPATH_FLOAT\s*\(/i, - /\bXPATH_INT\s*\(/i, - /\bXPATH_LONG\s*\(/i, - /\bXPATH_SHORT\s*\(/i, - /\bGET_JSON_OBJECT\s*\(/i, - /\bSTR_TO_MAP\s*\(/i, - /\bSENTENCES\s*\(/i, - /\bNGRAMS\s*\(/i, - /\bCONTEXT_NGRAMS\s*\(/i, - /\bWORDCOUNT\s*\(/i, - /\bCOLLECT_LIST\s*\(/i, - /\bCOLLECT_SET\s*\(/i, - /\bHISTOGRAM_NUMERIC\s*\(/i, - /\bPERCENTILE\s*\(/i, - /\bPERCENTILE_APPROX\s*\(/i, - /\bUDTF\b/i, - /\bUDAF\b/i, - /\bUDF\b/i, - /\bMAP\s* highestScore) { - bestDialect = dialect; - highestScore = score; - } - } - - // 如果没有明显的特征,尝试通用检测 - if (highestScore === 0) { - return detectGenericFeatures(normalizedSql); - } - - return bestDialect; -} - -/** - * 通用特征检测 - * @param {string} sql - SQL语句 - * @returns {string} - 检测到的SQL方言 - */ -function detectGenericFeatures(sql) { - const upperSql = sql.toUpperCase(); - - // 检测一些通用但有倾向性的特征 - if (upperSql.includes('LIMIT') && upperSql.includes('OFFSET')) { - if (upperSql.includes('AUTO_INCREMENT') || upperSql.includes('ENGINE=')) { - return 'mysql'; - } - return 'postgresql'; - } - - if (upperSql.includes('TOP ') && (upperSql.includes('IDENTITY') || upperSql.includes('NVARCHAR'))) { - return 'transactsql'; - } - - if (upperSql.includes('ROWNUM') || upperSql.includes('DUAL')) { - return 'plsql'; - } - - if (upperSql.includes('PRAGMA') || upperSql.includes('AUTOINCREMENT')) { - return 'sqlite'; - } - - if (upperSql.includes('STRUCT<') || upperSql.includes('ARRAY<')) { - return 'bigquery'; - } - - if (upperSql.includes('VARIANT') || upperSql.includes('$1') || upperSql.includes('QUALIFY')) { - return 'snowflake'; - } - - if (upperSql.includes('PARTITIONED BY') || upperSql.includes('STORED AS ORC') || upperSql.includes('LATERAL VIEW')) { - return 'hive'; - } - - if (upperSql.includes('USE KEYS') || upperSql.includes('UNNEST') && upperSql.includes('SATISFIES')) { - return 'n1ql'; - } - - if (upperSql.includes('DISTSTYLE') || upperSql.includes('SORTKEY') || upperSql.includes('DISTKEY')) { - return 'redshift'; - } - - if (upperSql.includes('COLUMNSTORE') || upperSql.includes('SHARD KEY') || upperSql.includes('REFERENCE TABLE')) { - return 'singlestoredb'; - } - - if (upperSql.includes('CACHE TABLE') || upperSql.includes('BROADCAST(') || upperSql.includes('USING DELTA')) { - return 'spark'; - } - - if (upperSql.includes('TIDB_VERSION') || upperSql.includes('AUTO_RANDOM') || upperSql.includes('AS OF TIMESTAMP')) { - return 'tidb'; - } - - if (upperSql.includes('ARRAY[') || upperSql.includes('MAP(') || upperSql.includes('APPROX_DISTINCT')) { - return 'trino'; - } - - if (upperSql.includes('DECFLOAT') || upperSql.includes('GENERATED ALWAYS') || upperSql.includes('FINAL TABLE')) { - return 'db2'; - } - - if (upperSql.includes('QSYS') || upperSql.includes('JOURNAL') || upperSql.includes('AS/400')) { - return 'db2i'; - } - - if (upperSql.includes('JSON_EXTRACT') && (upperSql.includes('ENGINE=') || upperSql.includes('SEQUENCE'))) { - return 'mariadb'; - } - - // 默认返回通用SQL - return 'sql'; -} diff --git a/frontend/src/common/prettier/plugins/sql/index.ts b/frontend/src/common/prettier/plugins/sql/index.ts new file mode 100644 index 0000000..e7ca46a --- /dev/null +++ b/frontend/src/common/prettier/plugins/sql/index.ts @@ -0,0 +1,140 @@ +/** + * Prettier Plugin for SQL formatting using SQL Format WebAssembly + * + * This plugin provides support for formatting SQL files using the SQL Format WASM implementation. + */ +import type { Plugin, Parser, Printer } from 'prettier'; + +// Import the SQL Format WASM module +import sqlFmtInit, { format, type Config } from './sql_fmt_vite.js'; + +const parserName = 'sql'; + +// Language configuration +const languages = [ + { + name: 'SQL', + aliases: ['sql'], + parsers: [parserName], + extensions: ['.sql'], + aceMode: 'sql', + tmScope: 'source.sql', + linguistLanguageId: 316, + vscodeLanguageIds: ['sql'] + } +]; + +// Parser configuration +const sqlParser: Parser = { + astFormat: parserName, + parse: (text: string) => text, + locStart: () => 0, + locEnd: (node: string) => node.length, +}; + +// Initialize SQL Format WASM module +let initPromise: Promise | null = null; +let isInitialized = false; + +function initSqlFmt(): Promise { + if (initPromise) { + return initPromise; + } + + initPromise = (async () => { + if (!isInitialized) { + await sqlFmtInit(); + isInitialized = true; + } + })(); + + return initPromise; +} + +// Printer configuration +const sqlPrinter: Printer = { + print: (path, options) => { + try { + if (!isInitialized) { + console.warn('SQL Format WASM module not initialized, returning original text'); + return (path as any).getValue ? (path as any).getValue() : path.node; + } + + const text = (path as any).getValue ? (path as any).getValue() : path.node; + const config = getSqlFmtConfig(options); + + // Format using SQL Format (synchronous call) + const formatted = format(text, 'index.sql', config); + + return formatted.trim(); + } catch (error) { + console.warn('SQL formatting failed:', error); + // Return original text if formatting fails + return (path as any).getValue ? (path as any).getValue() : path.node; + } + }, +}; + +// Helper function to create SQL Format config from Prettier options +function getSqlFmtConfig(options: any): Config { + const config: Config = {}; + + // Map Prettier options to SQL Format config + if (options.useTabs !== undefined) { + config.indent_style = options.useTabs ? 'tab' : 'space'; + } + + if (options.tabWidth !== undefined) { + config.indent_width = options.tabWidth; + } + + if (options.sqlUppercase !== undefined) { + config.uppercase = options.sqlUppercase; + } + + if (options.sqlLinesBetweenQueries !== undefined) { + config.lines_between_queries = options.sqlLinesBetweenQueries; + } + + return config; +} + +// Plugin options +const options = { + sqlUppercase: { + since: '0.0.1', + category: 'Format' as const, + type: 'boolean' as const, + default: false, + description: 'When set, changes reserved keywords to ALL CAPS' + }, + sqlLinesBetweenQueries: { + since: '0.0.1', + category: 'Format' as const, + type: 'int' as const, + default: 1, + description: 'Controls the number of line breaks after a query' + } +}; + +// Plugin definition +const sqlPlugin: Plugin = { + languages, + parsers: { + [parserName]: sqlParser, + }, + printers: { + [parserName]: sqlPrinter, + }, + options, +}; + +// Initialize the WASM module +initSqlFmt().catch(error => { + console.error('Failed to initialize SQL Format WASM module:', error); +}); + +export default sqlPlugin; +export { languages }; +export const parsers = sqlPlugin.parsers; +export const printers = sqlPlugin.printers; \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/sql/languages.js b/frontend/src/common/prettier/plugins/sql/languages.js deleted file mode 100644 index 5d09c1b..0000000 --- a/frontend/src/common/prettier/plugins/sql/languages.js +++ /dev/null @@ -1,30 +0,0 @@ -// SQL语言定义 -export const languages = [ - { - name: "SQL", - parsers: ["sql"], - extensions: [ - ".sql", - ".ddl", - ".dml", - ".hql", - ".psql", - ".plsql", - ".mysql", - ".mssql", - ".pgsql", - ".sqlite", - ".bigquery", - ".snowflake", - ".redshift", - ".db2", - ".n1ql", - ".cql" - ], - filenames: [ - "*.sql", - "*.ddl", - "*.dml" - ] - } -]; diff --git a/frontend/src/common/prettier/plugins/sql/sql.d.ts b/frontend/src/common/prettier/plugins/sql/sql.d.ts deleted file mode 100644 index c658172..0000000 --- a/frontend/src/common/prettier/plugins/sql/sql.d.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { AST, Option } from 'node-sql-parser'; -import { Options, ParserOptions, Plugin } from 'prettier'; -import { - FormatOptions, - FormatOptionsWithLanguage, -} from 'sql-formatter'; - -export type SqlBaseOptions = Option & - Partial< - | (FormatOptions & { dialect: string }) - | (FormatOptionsWithLanguage & { dialect?: never }) - > & { - formatter?: 'sql-formatter' | 'node-sql-parser' | 'sql-cst'; - params?: string; - paramTypes?: string; - autoDetectDialect?: boolean; - }; - -export type SqlOptions = ParserOptions & SqlBaseOptions; -export type SqlFormatOptions = Options & SqlBaseOptions; -export declare const languages: Plugin["languages"]; - -export declare const parsers: { - sql: { - parse(text: string, options?: SqlOptions): AST | string; - astFormat: 'sql'; - locStart(): number; - locEnd(): number; - }; -}; - -export declare const printers: Plugin["printers"]; - -export declare const options: Plugin["options"]; - -export declare function detectDialect(sql: string): string; - -declare const SqlPlugin: Plugin; - -export default SqlPlugin; diff --git a/frontend/src/common/prettier/plugins/sql/sql.mjs b/frontend/src/common/prettier/plugins/sql/sql.mjs deleted file mode 100644 index 57ff62c..0000000 --- a/frontend/src/common/prettier/plugins/sql/sql.mjs +++ /dev/null @@ -1,459 +0,0 @@ -import { JSOX } from 'jsox'; -import nodeSqlParser from 'node-sql-parser'; -import { - format, - formatDialect, -} from 'sql-formatter'; -import { detectDialect } from './detect.mjs'; -import { languages } from './languages.js'; - -const parser = new nodeSqlParser.Parser(); - -const SQL_FORMATTER = 'sql-formatter'; -const NODE_SQL_PARSER = 'node-sql-parser'; - -// Parsers -export const parsers = { - sql: { - parse(text, options = {}) { - const { formatter, type, database } = options; - - return formatter === SQL_FORMATTER - ? text - : parser.astify(text, { type, database }); - }, - astFormat: 'sql', - locStart: () => -1, - locEnd: () => -1, - }, -}; - -// Printers -export const printers = { - sql: { - print(path, options = {}) { - const value = path.node; - const { - formatter = SQL_FORMATTER, - type, - database, - dialect, - language, - params, - paramTypes, - autoDetectDialect = true, - ...formatOptions - } = options; - - let formatted; - - if (typeof value === 'string') { - // 准备sql-formatter选项 - const sqlFormatterOptions = { - ...formatOptions, - params: - params == null - ? undefined - : JSOX.parse(params), - paramTypes: - paramTypes == null - ? undefined - : JSOX.parse(paramTypes), - }; - - let finalLanguage = language; - let finalDialect = dialect; - - if (autoDetectDialect && !language && !dialect) { - const detectedDialect = detectDialect(value); - finalLanguage = detectedDialect; - } - - // 使用适当的格式化方法 - if (finalDialect != null) { - // 使用formatDialect方法 - formatted = formatDialect(value, { - ...sqlFormatterOptions, - dialect: JSOX.parse(finalDialect), - }); - } else { - // 使用format方法 - formatted = format(value, { - ...sqlFormatterOptions, - language: finalLanguage, - }); - } - } else { - // 使用node-sql-parser进行格式化 - formatted = parser.sqlify(value, { type, database }); - } - - return formatted + '\n'; - }, - }, -}; - -// 插件选项 -export const options = { - formatter: { - category: 'Config', - type: 'choice', - default: SQL_FORMATTER, - description: 'Choose which formatter to be used', - choices: [ - { - value: SQL_FORMATTER, - description: 'use `sql-formatter` as formatter', - }, - { - value: NODE_SQL_PARSER, - description: 'use `node-sql-parser` as formatter', - }, - ], - }, - autoDetectDialect: { - category: 'Config', - type: 'boolean', - default: true, - description: 'Automatically detect SQL dialect if language/dialect is not specified', - }, - dialect: { - category: 'Config', - type: 'string', - description: 'SQL dialect for `sql-formatter` formatDialect()', - }, - language: { - category: 'Config', - type: 'choice', - default: 'sql', - description: 'SQL dialect for `sql-formatter` format()', - choices: [ - { - value: 'sql', - description: 'Standard SQL: https://en.wikipedia.org/wiki/SQL:2011', - }, - { - value: 'bigquery', - description: - 'Google Standard SQL (Bigquery): https://cloud.google.com/bigquery', - }, - { - value: 'db2', - description: 'IBM DB2: https://www.ibm.com/products/db2', - }, - { - value: 'db2i', - description: - 'IBM DB2i (experimental): https://www.ibm.com/docs/en/i/7.5?topic=overview-db2-i', - }, - { - value: 'hive', - description: 'Apache Hive: https://hive.apache.org', - }, - { - value: 'mariadb', - description: 'MariaDB: https://mariadb.com', - }, - { - value: 'mysql', - description: 'MySQL: https://www.mysql.com', - }, - { - value: 'n1ql', - description: - 'Couchbase N1QL: https://www.couchbase.com/products/n1ql', - }, - { - value: 'plsql', - description: - 'Oracle PL/SQL: https://www.oracle.com/database/technologies/appdev/plsql.html', - }, - { - value: 'postgresql', - description: 'PostgreSQL: https://www.postgresql.org', - }, - { - value: 'redshift', - description: - 'Amazon Redshift: https://docs.aws.amazon.com/redshift/latest/dg/cm_chap_SQLCommandRef.html', - }, - { - value: 'singlestoredb', - description: - 'SingleStoreDB: https://docs.singlestore.com/db/v7.8/en/introduction/singlestore-documentation.html', - }, - { - value: 'snowflake', - description: 'Snowflake: https://docs.snowflake.com', - }, - { - value: 'spark', - description: 'Spark: https://spark.apache.org', - }, - { - value: 'sqlite', - description: 'SQLite: https://www.sqlite.org', - }, - { - value: 'transactsql', - description: - 'SQL Server Transact-SQL: https://docs.microsoft.com/en-us/sql/sql-server/', - }, - { - value: 'tsql', - description: - 'SQL Server Transact-SQL: https://docs.microsoft.com/en-us/sql/sql-server/', - }, - { - value: 'trino', - description: 'Trino: https://trino.io', - }, - ], - }, - keywordCase: { - category: 'Output', - type: 'choice', - default: 'preserve', - description: - 'Converts reserved keywords to upper- or lowercase for `sql-formatter`', - choices: [ - { - value: 'preserve', - description: 'preserves the original case of reserved keywords', - }, - { - value: 'upper', - description: 'converts reserved keywords to uppercase', - }, - { - value: 'lower', - description: 'converts reserved keywords to lowercase', - }, - ], - }, - dataTypeCase: { - category: 'Output', - type: 'choice', - default: 'preserve', - description: - 'Converts data types to upper- or lowercase for `sql-formatter`', - choices: [ - { - value: 'preserve', - description: 'preserves the original case of data types', - }, - { - value: 'upper', - description: 'converts data types to uppercase', - }, - { - value: 'lower', - description: 'converts data types to lowercase', - }, - ], - }, - functionCase: { - category: 'Output', - type: 'choice', - default: 'preserve', - description: - 'Converts functions to upper- or lowercase for `sql-formatter`', - choices: [ - { - value: 'preserve', - description: 'preserves the original case of functions', - }, - { - value: 'upper', - description: 'converts functions to uppercase', - }, - { - value: 'lower', - description: 'converts functions to lowercase', - }, - ], - }, - identifierCase: { - category: 'Output', - type: 'choice', - default: 'preserve', - description: - 'Converts identifiers to upper- or lowercase for `sql-formatter`. Only unquoted identifiers are converted. (experimental)', - choices: [ - { - value: 'preserve', - description: 'preserves the original case of identifiers', - }, - { - value: 'upper', - description: 'converts identifiers to uppercase', - }, - { - value: 'lower', - description: 'converts identifiers to lowercase', - }, - ], - }, - uppercase: { - category: 'Output', - type: 'boolean', - deprecated: '0.7.0', - description: 'Use `keywordCase` option instead', - }, - indentStyle: { - category: 'Format', - type: 'choice', - default: 'standard', - description: `Switches between different indentation styles for \`sql-formatter\`. - - Caveats of using \`"tabularLeft"\` and \`"tabularRight"\`: - - - \`tabWidth\` option is ignored. Indentation will always be 10 spaces, regardless of what is specified by \`tabWidth\``, - choices: [ - { - value: 'standard', - description: - 'indents code by the amount specified by `tabWidth` option', - }, - { - value: 'tabularLeft', - description: - 'indents in tabular style with 10 spaces, aligning keywords to left', - }, - { - value: 'tabularRight', - description: - 'indents in tabular style with 10 spaces, aligning keywords to right', - }, - ], - }, - logicalOperatorNewline: { - category: 'Format', - type: 'choice', - default: 'before', - description: - 'Decides newline placement before or after logical operators (AND, OR, XOR)', - choices: [ - { - value: 'before', - description: 'adds newline before the operator', - }, - { - value: 'after', - description: 'adds newline after the operator', - }, - ], - }, - expressionWidth: { - category: 'Format', - type: 'int', - default: 50, - description: - 'Determines maximum length of parenthesized expressions for `sql-formatter`', - }, - linesBetweenQueries: { - category: 'Format', - type: 'int', - default: 1, - description: - 'Decides how many empty lines to leave between SQL statements for `sql-formatter`', - }, - denseOperators: { - category: 'Format', - type: 'boolean', - default: false, - description: - 'Decides whitespace around operators for `sql-formatter`. Does not apply to logical operators (AND, OR, XOR).', - }, - newlineBeforeSemicolon: { - category: 'Format', - type: 'boolean', - default: false, - description: - 'Whether to place query separator (`;`) on a separate line for `sql-formatter`', - }, - params: { - category: 'Format', - type: 'string', - description: - 'Specifies `JSOX` **stringified** parameter values to fill in for placeholders inside SQL for `sql-formatter`. This option is designed to be used through API (though nothing really prevents usage from command line).', - }, - paramTypes: { - category: 'Config', - type: 'string', - description: - 'Specifies `JSOX` **stringified** parameter types to support when parsing SQL prepared statements for `sql-formatter`.', - }, - type: { - category: 'Config', - type: 'choice', - default: 'table', - description: 'Check the SQL with Authority List for `node-sql-parser`', - choices: [ - { - value: 'table', - description: '`table` mode', - }, - { - value: 'column', - description: '`column` mode', - }, - ], - }, - database: { - category: 'Config', - type: 'choice', - default: 'mysql', - description: 'SQL dialect for `node-sql-parser`', - choices: [ - { - value: 'bigquery', - description: 'BigQuery: https://cloud.google.com/bigquery', - }, - { - value: 'db2', - description: 'IBM DB2: https://www.ibm.com/analytics/db2', - }, - { - value: 'hive', - description: 'Hive: https://hive.apache.org', - }, - { - value: 'mariadb', - description: 'MariaDB: https://mariadb.com', - }, - { - value: 'mysql', - description: 'MySQL: https://www.mysql.com', - }, - { - value: 'postgresql', - description: 'PostgreSQL: https://www.postgresql.org', - }, - { - value: 'transactsql', - description: - 'TransactSQL: https://docs.microsoft.com/en-us/sql/t-sql', - }, - { - value: 'flinksql', - description: - 'FlinkSQL: https://ci.apache.org/projects/flink/flink-docs-stable', - }, - { - value: 'snowflake', - description: 'Snowflake (alpha): https://docs.snowflake.com', - }, - ], - }, -}; - -const SqlPlugin = { - languages, - parsers, - printers, - options, -}; - -export { languages }; -export default SqlPlugin; \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/sql/sql_fmt.d.ts b/frontend/src/common/prettier/plugins/sql/sql_fmt.d.ts new file mode 100644 index 0000000..41efd3b --- /dev/null +++ b/frontend/src/common/prettier/plugins/sql/sql_fmt.d.ts @@ -0,0 +1,58 @@ +/* tslint:disable */ +/* eslint-disable */ +export function format(input: string, filename: string, config?: Config): string; + +interface LayoutConfig { + indent_style?: "tab" | "space"; + indent_width?: number; +} + + +export interface Config extends LayoutConfig { + /** + * When set, changes reserved keywords to ALL CAPS + * + * Default: false + */ + uppercase?: boolean; + /** + * Controls the number of line breaks after a query + * + * Default: 1 + */ + lines_between_queries?: number; +} + + +export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module; + +export interface InitOutput { + readonly memory: WebAssembly.Memory; + readonly format: (a: number, b: number, c: number, d: number, e: number, f: number) => void; + readonly __wbindgen_export_0: (a: number, b: number) => number; + readonly __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number; + readonly __wbindgen_export_2: (a: number) => void; + readonly __wbindgen_add_to_stack_pointer: (a: number) => number; + readonly __wbindgen_export_3: (a: number, b: number, c: number) => void; +} + +export type SyncInitInput = BufferSource | WebAssembly.Module; +/** +* Instantiates the given `module`, which can either be bytes or +* a precompiled `WebAssembly.Module`. +* +* @param {{ module: SyncInitInput }} module - Passing `SyncInitInput` directly is deprecated. +* +* @returns {InitOutput} +*/ +export function initSync(module: { module: SyncInitInput } | SyncInitInput): InitOutput; + +/** +* If `module_or_path` is {RequestInfo} or {URL}, makes a request and +* for everything else, calls `WebAssembly.instantiate` directly. +* +* @param {{ module_or_path: InitInput | Promise }} module_or_path - Passing `InitInput` directly is deprecated. +* +* @returns {Promise} +*/ +export default function __wbg_init (module_or_path?: { module_or_path: InitInput | Promise } | InitInput | Promise): Promise; diff --git a/frontend/src/common/prettier/plugins/sql/sql_fmt.js b/frontend/src/common/prettier/plugins/sql/sql_fmt.js new file mode 100644 index 0000000..ebc5e2b --- /dev/null +++ b/frontend/src/common/prettier/plugins/sql/sql_fmt.js @@ -0,0 +1,524 @@ +let wasm; + +const heap = new Array(128).fill(undefined); + +heap.push(undefined, null, true, false); + +function getObject(idx) { return heap[idx]; } + +let WASM_VECTOR_LEN = 0; + +let cachedUint8ArrayMemory0 = null; + +function getUint8ArrayMemory0() { + if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) { + cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer); + } + return cachedUint8ArrayMemory0; +} + +const cachedTextEncoder = (typeof TextEncoder !== 'undefined' ? new TextEncoder('utf-8') : { encode: () => { throw Error('TextEncoder not available') } } ); + +const encodeString = (typeof cachedTextEncoder.encodeInto === 'function' + ? function (arg, view) { + return cachedTextEncoder.encodeInto(arg, view); +} + : function (arg, view) { + const buf = cachedTextEncoder.encode(arg); + view.set(buf); + return { + read: arg.length, + written: buf.length + }; +}); + +function passStringToWasm0(arg, malloc, realloc) { + + if (realloc === undefined) { + const buf = cachedTextEncoder.encode(arg); + const ptr = malloc(buf.length, 1) >>> 0; + getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf); + WASM_VECTOR_LEN = buf.length; + return ptr; + } + + let len = arg.length; + let ptr = malloc(len, 1) >>> 0; + + const mem = getUint8ArrayMemory0(); + + let offset = 0; + + for (; offset < len; offset++) { + const code = arg.charCodeAt(offset); + if (code > 0x7F) break; + mem[ptr + offset] = code; + } + + if (offset !== len) { + if (offset !== 0) { + arg = arg.slice(offset); + } + ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0; + const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len); + const ret = encodeString(arg, view); + + offset += ret.written; + ptr = realloc(ptr, len, offset, 1) >>> 0; + } + + WASM_VECTOR_LEN = offset; + return ptr; +} + +let cachedDataViewMemory0 = null; + +function getDataViewMemory0() { + if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) { + cachedDataViewMemory0 = new DataView(wasm.memory.buffer); + } + return cachedDataViewMemory0; +} + +let heap_next = heap.length; + +function addHeapObject(obj) { + if (heap_next === heap.length) heap.push(heap.length + 1); + const idx = heap_next; + heap_next = heap[idx]; + + heap[idx] = obj; + return idx; +} + +function handleError(f, args) { + try { + return f.apply(this, args); + } catch (e) { + wasm.__wbindgen_export_2(addHeapObject(e)); + } +} + +function isLikeNone(x) { + return x === undefined || x === null; +} + +function debugString(val) { + // primitive types + const type = typeof val; + if (type == 'number' || type == 'boolean' || val == null) { + return `${val}`; + } + if (type == 'string') { + return `"${val}"`; + } + if (type == 'symbol') { + const description = val.description; + if (description == null) { + return 'Symbol'; + } else { + return `Symbol(${description})`; + } + } + if (type == 'function') { + const name = val.name; + if (typeof name == 'string' && name.length > 0) { + return `Function(${name})`; + } else { + return 'Function'; + } + } + // objects + if (Array.isArray(val)) { + const length = val.length; + let debug = '['; + if (length > 0) { + debug += debugString(val[0]); + } + for(let i = 1; i < length; i++) { + debug += ', ' + debugString(val[i]); + } + debug += ']'; + return debug; + } + // Test for built-in + const builtInMatches = /\[object ([^\]]+)\]/.exec(toString.call(val)); + let className; + if (builtInMatches && builtInMatches.length > 1) { + className = builtInMatches[1]; + } else { + // Failed to match the standard '[object ClassName]' + return toString.call(val); + } + if (className == 'Object') { + // we're a user defined class or Object + // JSON.stringify avoids problems with cycles, and is generally much + // easier than looping through ownProperties of `val`. + try { + return 'Object(' + JSON.stringify(val) + ')'; + } catch (_) { + return 'Object'; + } + } + // errors + if (val instanceof Error) { + return `${val.name}: ${val.message}\n${val.stack}`; + } + // TODO we could test for more things here, like `Set`s and `Map`s. + return className; +} + +const cachedTextDecoder = (typeof TextDecoder !== 'undefined' ? new TextDecoder('utf-8', { ignoreBOM: true, fatal: true }) : { decode: () => { throw Error('TextDecoder not available') } } ); + +if (typeof TextDecoder !== 'undefined') { cachedTextDecoder.decode(); }; + +function getStringFromWasm0(ptr, len) { + ptr = ptr >>> 0; + return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len)); +} + +function dropObject(idx) { + if (idx < 132) return; + heap[idx] = heap_next; + heap_next = idx; +} + +function takeObject(idx) { + const ret = getObject(idx); + dropObject(idx); + return ret; +} +/** + * @param {string} input + * @param {string} filename + * @param {Config | undefined} [config] + * @returns {string} + */ +export function format(input, filename, config) { + let deferred4_0; + let deferred4_1; + try { + const retptr = wasm.__wbindgen_add_to_stack_pointer(-16); + const ptr0 = passStringToWasm0(input, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len0 = WASM_VECTOR_LEN; + const ptr1 = passStringToWasm0(filename, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len1 = WASM_VECTOR_LEN; + wasm.format(retptr, ptr0, len0, ptr1, len1, isLikeNone(config) ? 0 : addHeapObject(config)); + var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true); + var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true); + var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true); + var r3 = getDataViewMemory0().getInt32(retptr + 4 * 3, true); + var ptr3 = r0; + var len3 = r1; + if (r3) { + ptr3 = 0; len3 = 0; + throw takeObject(r2); + } + deferred4_0 = ptr3; + deferred4_1 = len3; + return getStringFromWasm0(ptr3, len3); + } finally { + wasm.__wbindgen_add_to_stack_pointer(16); + wasm.__wbindgen_export_3(deferred4_0, deferred4_1, 1); + } +} + +async function __wbg_load(module, imports) { + if (typeof Response === 'function' && module instanceof Response) { + if (typeof WebAssembly.instantiateStreaming === 'function') { + try { + return await WebAssembly.instantiateStreaming(module, imports); + + } catch (e) { + if (module.headers.get('Content-Type') != 'application/wasm') { + console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e); + + } else { + throw e; + } + } + } + + const bytes = await module.arrayBuffer(); + return await WebAssembly.instantiate(bytes, imports); + + } else { + const instance = await WebAssembly.instantiate(module, imports); + + if (instance instanceof WebAssembly.Instance) { + return { instance, module }; + + } else { + return instance; + } + } +} + +function __wbg_get_imports() { + const imports = {}; + imports.wbg = {}; + imports.wbg.__wbg_String_8f0eb39a4a4c2f66 = function(arg0, arg1) { + const ret = String(getObject(arg1)); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbg_buffer_61b7ce01341d7f88 = function(arg0) { + const ret = getObject(arg0).buffer; + return addHeapObject(ret); + }; + imports.wbg.__wbg_call_b0d8e36992d9900d = function() { return handleError(function (arg0, arg1) { + const ret = getObject(arg0).call(getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_done_f22c1561fa919baa = function(arg0) { + const ret = getObject(arg0).done; + return ret; + }; + imports.wbg.__wbg_entries_4f2bb9b0d701c0f6 = function(arg0) { + const ret = Object.entries(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_get_9aa3dff3f0266054 = function(arg0, arg1) { + const ret = getObject(arg0)[arg1 >>> 0]; + return addHeapObject(ret); + }; + imports.wbg.__wbg_get_bbccf8970793c087 = function() { return handleError(function (arg0, arg1) { + const ret = Reflect.get(getObject(arg0), getObject(arg1)); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_instanceof_ArrayBuffer_670ddde44cdb2602 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof ArrayBuffer; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_Map_98ecb30afec5acdb = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof Map; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_instanceof_Uint8Array_28af5bc19d6acad8 = function(arg0) { + let result; + try { + result = getObject(arg0) instanceof Uint8Array; + } catch (_) { + result = false; + } + const ret = result; + return ret; + }; + imports.wbg.__wbg_isArray_1ba11a930108ec51 = function(arg0) { + const ret = Array.isArray(getObject(arg0)); + return ret; + }; + imports.wbg.__wbg_isSafeInteger_12f5549b2fca23f4 = function(arg0) { + const ret = Number.isSafeInteger(getObject(arg0)); + return ret; + }; + imports.wbg.__wbg_iterator_23604bb983791576 = function() { + const ret = Symbol.iterator; + return addHeapObject(ret); + }; + imports.wbg.__wbg_length_65d1cd11729ced11 = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_length_d65cf0786bfc5739 = function(arg0) { + const ret = getObject(arg0).length; + return ret; + }; + imports.wbg.__wbg_new_3ff5b33b1ce712df = function(arg0) { + const ret = new Uint8Array(getObject(arg0)); + return addHeapObject(ret); + }; + imports.wbg.__wbg_next_01dd9234a5bf6d05 = function() { return handleError(function (arg0) { + const ret = getObject(arg0).next(); + return addHeapObject(ret); + }, arguments) }; + imports.wbg.__wbg_next_137428deb98342b0 = function(arg0) { + const ret = getObject(arg0).next; + return addHeapObject(ret); + }; + imports.wbg.__wbg_set_23d69db4e5c66a6e = function(arg0, arg1, arg2) { + getObject(arg0).set(getObject(arg1), arg2 >>> 0); + }; + imports.wbg.__wbg_value_4c32fd138a88eee2 = function(arg0) { + const ret = getObject(arg0).value; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_as_number = function(arg0) { + const ret = +getObject(arg0); + return ret; + }; + imports.wbg.__wbindgen_bigint_from_i64 = function(arg0) { + const ret = arg0; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_bigint_from_u64 = function(arg0) { + const ret = BigInt.asUintN(64, arg0); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) { + const v = getObject(arg1); + const ret = typeof(v) === 'bigint' ? v : undefined; + getDataViewMemory0().setBigInt64(arg0 + 8 * 1, isLikeNone(ret) ? BigInt(0) : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); + }; + imports.wbg.__wbindgen_boolean_get = function(arg0) { + const v = getObject(arg0); + const ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2; + return ret; + }; + imports.wbg.__wbindgen_debug_string = function(arg0, arg1) { + const ret = debugString(getObject(arg1)); + const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + const len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbindgen_error_new = function(arg0, arg1) { + const ret = new Error(getStringFromWasm0(arg0, arg1)); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_in = function(arg0, arg1) { + const ret = getObject(arg0) in getObject(arg1); + return ret; + }; + imports.wbg.__wbindgen_is_bigint = function(arg0) { + const ret = typeof(getObject(arg0)) === 'bigint'; + return ret; + }; + imports.wbg.__wbindgen_is_function = function(arg0) { + const ret = typeof(getObject(arg0)) === 'function'; + return ret; + }; + imports.wbg.__wbindgen_is_object = function(arg0) { + const val = getObject(arg0); + const ret = typeof(val) === 'object' && val !== null; + return ret; + }; + imports.wbg.__wbindgen_jsval_eq = function(arg0, arg1) { + const ret = getObject(arg0) === getObject(arg1); + return ret; + }; + imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) { + const ret = getObject(arg0) == getObject(arg1); + return ret; + }; + imports.wbg.__wbindgen_memory = function() { + const ret = wasm.memory; + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_number_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'number' ? obj : undefined; + getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true); + }; + imports.wbg.__wbindgen_object_clone_ref = function(arg0) { + const ret = getObject(arg0); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_object_drop_ref = function(arg0) { + takeObject(arg0); + }; + imports.wbg.__wbindgen_string_get = function(arg0, arg1) { + const obj = getObject(arg1); + const ret = typeof(obj) === 'string' ? obj : undefined; + var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export_0, wasm.__wbindgen_export_1); + var len1 = WASM_VECTOR_LEN; + getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true); + getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true); + }; + imports.wbg.__wbindgen_string_new = function(arg0, arg1) { + const ret = getStringFromWasm0(arg0, arg1); + return addHeapObject(ret); + }; + imports.wbg.__wbindgen_throw = function(arg0, arg1) { + throw new Error(getStringFromWasm0(arg0, arg1)); + }; + + return imports; +} + +function __wbg_init_memory(imports, memory) { + +} + +function __wbg_finalize_init(instance, module) { + wasm = instance.exports; + __wbg_init.__wbindgen_wasm_module = module; + cachedDataViewMemory0 = null; + cachedUint8ArrayMemory0 = null; + + + + return wasm; +} + +function initSync(module) { + if (wasm !== undefined) return wasm; + + + if (typeof module !== 'undefined') { + if (Object.getPrototypeOf(module) === Object.prototype) { + ({module} = module) + } else { + console.warn('using deprecated parameters for `initSync()`; pass a single object instead') + } + } + + const imports = __wbg_get_imports(); + + __wbg_init_memory(imports); + + if (!(module instanceof WebAssembly.Module)) { + module = new WebAssembly.Module(module); + } + + const instance = new WebAssembly.Instance(module, imports); + + return __wbg_finalize_init(instance, module); +} + +async function __wbg_init(module_or_path) { + if (wasm !== undefined) return wasm; + + + if (typeof module_or_path !== 'undefined') { + if (Object.getPrototypeOf(module_or_path) === Object.prototype) { + ({module_or_path} = module_or_path) + } else { + console.warn('using deprecated parameters for the initialization function; pass a single object instead') + } + } + + if (typeof module_or_path === 'undefined') { + module_or_path = new URL('sql_fmt_bg.wasm', import.meta.url); + } + const imports = __wbg_get_imports(); + + if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) { + module_or_path = fetch(module_or_path); + } + + __wbg_init_memory(imports); + + const { instance, module } = await __wbg_load(await module_or_path, imports); + + return __wbg_finalize_init(instance, module); +} + +export { initSync }; +export default __wbg_init; diff --git a/frontend/src/common/prettier/plugins/sql/sql_fmt_bg.wasm b/frontend/src/common/prettier/plugins/sql/sql_fmt_bg.wasm new file mode 100644 index 0000000000000000000000000000000000000000..47299ed49740ffec9c04be34321594bd0d22621b GIT binary patch literal 195086 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 void; +export const __wbindgen_export_0: (a: number, b: number) => number; +export const __wbindgen_export_1: (a: number, b: number, c: number, d: number) => number; +export const __wbindgen_export_2: (a: number) => void; +export const __wbindgen_add_to_stack_pointer: (a: number) => number; +export const __wbindgen_export_3: (a: number, b: number, c: number) => void; diff --git a/frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_node.js b/frontend/src/common/prettier/plugins/sql/sql_fmt_node.js similarity index 53% rename from frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_node.js rename to frontend/src/common/prettier/plugins/sql/sql_fmt_node.js index c49c6ca..221fd18 100644 --- a/frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_node.js +++ b/frontend/src/common/prettier/plugins/sql/sql_fmt_node.js @@ -1,10 +1,10 @@ import fs from "node:fs/promises"; -import initAsync from "./web_fmt.js"; +import initAsync from "./sql_fmt.js"; -const wasm = new URL("./web_fmt_bg.wasm", import.meta.url); +const wasm = new URL("./sql_fmt_bg.wasm", import.meta.url); export default function __wbg_init(init = { module_or_path: fs.readFile(wasm) }) { return initAsync(init); } -export * from "./web_fmt.js"; +export * from "./sql_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/sql/sql_fmt_vite.js b/frontend/src/common/prettier/plugins/sql/sql_fmt_vite.js new file mode 100644 index 0000000..e3f6eaf --- /dev/null +++ b/frontend/src/common/prettier/plugins/sql/sql_fmt_vite.js @@ -0,0 +1,8 @@ +import initAsync from "./sql_fmt.js"; +import wasm from "./sql_fmt_bg.wasm?url"; + +export default function __wbg_init(input = { module_or_path: wasm }) { + return initAsync(input); +} + +export * from "./sql_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/sql/src/build.sh b/frontend/src/common/prettier/plugins/sql/src/build.sh new file mode 100644 index 0000000..2cfc195 --- /dev/null +++ b/frontend/src/common/prettier/plugins/sql/src/build.sh @@ -0,0 +1,3 @@ +cd $(dirname $0)/.. +wasm-pack build --target=web --scope=wasm-fmt + diff --git a/frontend/src/common/prettier/plugins/sql/src/lib.rs b/frontend/src/common/prettier/plugins/sql/src/lib.rs new file mode 100644 index 0000000..66bd168 --- /dev/null +++ b/frontend/src/common/prettier/plugins/sql/src/lib.rs @@ -0,0 +1,97 @@ +use serde::Deserialize; + +use sqlformat::{FormatOptions, QueryParams}; +use wasm_bindgen::prelude::wasm_bindgen; + +#[wasm_bindgen] +pub fn format(input: &str, filename: &str, config: Option) -> Result { + let _ = filename; + + let config = config + .map(|x| serde_wasm_bindgen::from_value::(x.clone())) + .transpose() + .map_err(|op| op.to_string())? + .unwrap_or_default(); + + Ok(sqlformat::format(input, &QueryParams::None, &config.into())) +} + +#[wasm_bindgen(typescript_custom_section)] +const TS_Config: &'static str = r#" +interface LayoutConfig { + indent_style?: "tab" | "space"; + indent_width?: number; +}"#; + +#[wasm_bindgen(typescript_custom_section)] +const TS_Config: &'static str = r#" +export interface Config extends LayoutConfig { + /** + * When set, changes reserved keywords to ALL CAPS + * + * Default: false + */ + uppercase?: boolean; + /** + * Controls the number of line breaks after a query + * + * Default: 1 + */ + lines_between_queries?: number; +}"#; + +#[wasm_bindgen] +extern "C" { + #[wasm_bindgen(typescript_type = "Config")] + pub type Config; +} + +#[derive(Deserialize, Clone, Copy)] +enum IndentStyle { + #[serde(rename = "tab")] + Tab, + #[serde(rename = "space")] + Space, +} + +#[derive(Deserialize, Clone, Default)] +struct LayoutConfig { + #[serde(alias = "indentStyle")] + indent_style: Option, + #[serde(alias = "indentWidth")] + indent_width: Option, +} + +#[derive(Deserialize, Clone, Default)] +struct SQLConfig { + #[serde(flatten)] + layout: LayoutConfig, + + pub uppercase: Option, + + #[serde(alias = "linesBetweenQueries")] + pub lines_between_queries: Option, +} + +impl<'a> From for FormatOptions<'a> { + fn from(val: SQLConfig) -> Self { + let mut config = FormatOptions::default(); + + let indent_width = val.layout.indent_width.unwrap_or(2); + + if let Some(indent_style) = val.layout.indent_style { + config.indent = match indent_style { + IndentStyle::Tab => sqlformat::Indent::Tabs, + IndentStyle::Space => sqlformat::Indent::Spaces(indent_width), + }; + } + + config.uppercase = val.uppercase; + + if let Some(lines_between_queries) = val.lines_between_queries { + config.lines_between_queries = lines_between_queries; + } + + config + } +} diff --git a/frontend/src/common/prettier/plugins/web/json_fmt/extra/.npmignore b/frontend/src/common/prettier/plugins/web/json_fmt/extra/.npmignore deleted file mode 100644 index 1ee7305..0000000 --- a/frontend/src/common/prettier/plugins/web/json_fmt/extra/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -*.tgz -jsr.jsonc \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_node.js b/frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_node.js deleted file mode 100644 index bf3f3df..0000000 --- a/frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_node.js +++ /dev/null @@ -1,10 +0,0 @@ -import fs from "node:fs/promises"; -import initAsync from "./json_fmt.js"; - -const wasm = new URL("./json_fmt_bg.wasm", import.meta.url); - -export default function __wbg_init(init = { module_or_path: fs.readFile(wasm) }) { - return initAsync(init); -} - -export * from "./json_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_vite.js b/frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_vite.js deleted file mode 100644 index bfe6f22..0000000 --- a/frontend/src/common/prettier/plugins/web/json_fmt/extra/json_fmt_vite.js +++ /dev/null @@ -1,8 +0,0 @@ -import initAsync from "./json_fmt.js"; -import wasm from "./json_fmt_bg.wasm?url"; - -export default function __wbg_init(input = { module_or_path: wasm }) { - return initAsync(input); -} - -export * from "./json_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/web/json_fmt/scripts/package.mjs b/frontend/src/common/prettier/plugins/web/json_fmt/scripts/package.mjs deleted file mode 100644 index 1d16430..0000000 --- a/frontend/src/common/prettier/plugins/web/json_fmt/scripts/package.mjs +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env node -import process from "node:process"; -import path from "node:path"; -import fs from "node:fs"; - -const pkg_path = path.resolve(process.cwd(), process.argv[2]); -const pkg_text = fs.readFileSync(pkg_path, { encoding: "utf-8" }); -const pkg_json = JSON.parse(pkg_text); - -delete pkg_json.files; - -pkg_json.main = pkg_json.module; -pkg_json.type = "module"; -pkg_json.publishConfig = { - access: "public", -}; -pkg_json.exports = { - ".": { - types: "./json_fmt.d.ts", - node: "./json_fmt_node.js", - default: "./json_fmt.js", - }, - "./vite": { - types: "./json_fmt.d.ts", - default: "./json_fmt_vite.js", - }, - "./package.json": "./package.json", - "./*": "./*", -}; - -fs.writeFileSync(pkg_path, JSON.stringify(pkg_json, null, 4)); - -// JSR - -const jsr_path = path.resolve(pkg_path, "..", "jsr.jsonc"); -pkg_json.name = "@fmt/json-fmt"; -pkg_json.exports = "./json_fmt.js"; -pkg_json.exclude = ["!**", "*.tgz"]; -fs.writeFileSync(jsr_path, JSON.stringify(pkg_json, null, 4)); diff --git a/frontend/src/common/prettier/plugins/web/json_fmt/scripts/build.sh b/frontend/src/common/prettier/plugins/web/json_fmt/src/build.sh similarity index 57% rename from frontend/src/common/prettier/plugins/web/json_fmt/scripts/build.sh rename to frontend/src/common/prettier/plugins/web/json_fmt/src/build.sh index fb3892a..4d99ab9 100644 --- a/frontend/src/common/prettier/plugins/web/json_fmt/scripts/build.sh +++ b/frontend/src/common/prettier/plugins/web/json_fmt/src/build.sh @@ -4,8 +4,3 @@ crates_dir=$(pwd) cd ../.. wasm-pack build --target=web --scope=wasm-fmt crates/json_fmt -cd $crates_dir - -cp -R ./extra/. ./pkg/ - -./scripts/package.mjs ./pkg/package.json diff --git a/frontend/src/common/prettier/plugins/web/web_fmt/extra/.npmignore b/frontend/src/common/prettier/plugins/web/web_fmt/extra/.npmignore deleted file mode 100644 index 1ee7305..0000000 --- a/frontend/src/common/prettier/plugins/web/web_fmt/extra/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -*.tgz -jsr.jsonc \ No newline at end of file diff --git a/frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_vite.js b/frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_vite.js deleted file mode 100644 index b0462b9..0000000 --- a/frontend/src/common/prettier/plugins/web/web_fmt/extra/web_fmt_vite.js +++ /dev/null @@ -1,8 +0,0 @@ -import initAsync from "./web_fmt.js"; -import wasm from "./web_fmt_bg.wasm?url"; - -export default function __wbg_init(input = { module_or_path: wasm }) { - return initAsync(input); -} - -export * from "./web_fmt.js"; diff --git a/frontend/src/common/prettier/plugins/web/web_fmt/scripts/package.mjs b/frontend/src/common/prettier/plugins/web/web_fmt/scripts/package.mjs deleted file mode 100644 index c94c56b..0000000 --- a/frontend/src/common/prettier/plugins/web/web_fmt/scripts/package.mjs +++ /dev/null @@ -1,39 +0,0 @@ -#!/usr/bin/env node -import process from "node:process"; -import path from "node:path"; -import fs from "node:fs"; - -const pkg_path = path.resolve(process.cwd(), process.argv[2]); -const pkg_text = fs.readFileSync(pkg_path, { encoding: "utf-8" }); -const pkg_json = JSON.parse(pkg_text); - -delete pkg_json.files; - -pkg_json.main = pkg_json.module; -pkg_json.type = "module"; -pkg_json.publishConfig = { - access: "public", -}; -pkg_json.exports = { - ".": { - types: "./web_fmt.d.ts", - node: "./web_fmt_node.js", - default: "./web_fmt.js", - }, - "./vite": { - types: "./web_fmt.d.ts", - default: "./web_fmt_vite.js", - }, - "./package.json": "./package.json", - "./*": "./*", -}; - -fs.writeFileSync(pkg_path, JSON.stringify(pkg_json, null, 4)); - -// JSR - -const jsr_path = path.resolve(pkg_path, "..", "jsr.jsonc"); -pkg_json.name = "@fmt/web-fmt"; -pkg_json.exports = "./web_fmt.js"; -pkg_json.exclude = ["!**", "*.tgz"]; -fs.writeFileSync(jsr_path, JSON.stringify(pkg_json, null, 4)); diff --git a/frontend/src/common/prettier/plugins/web/web_fmt/scripts/build.sh b/frontend/src/common/prettier/plugins/web/web_fmt/src/build.sh similarity index 57% rename from frontend/src/common/prettier/plugins/web/web_fmt/scripts/build.sh rename to frontend/src/common/prettier/plugins/web/web_fmt/src/build.sh index 4b2ec50..bb27bb0 100644 --- a/frontend/src/common/prettier/plugins/web/web_fmt/scripts/build.sh +++ b/frontend/src/common/prettier/plugins/web/web_fmt/src/build.sh @@ -4,8 +4,3 @@ crates_dir=$(pwd) cd ../.. wasm-pack build --target=web --scope=wasm-fmt crates/web_fmt -cd $crates_dir - -cp -R ./extra/. ./pkg/ - -./scripts/package.mjs ./pkg/package.json diff --git a/frontend/src/views/editor/extensions/codeblock/lang-parser/languages.ts b/frontend/src/views/editor/extensions/codeblock/lang-parser/languages.ts index a94d9d0..cfa6873 100644 --- a/frontend/src/views/editor/extensions/codeblock/lang-parser/languages.ts +++ b/frontend/src/views/editor/extensions/codeblock/lang-parser/languages.ts @@ -39,7 +39,7 @@ import cssPrettierPlugin from "prettier/plugins/postcss" import markdownPrettierPlugin from "prettier/plugins/markdown" import yamlPrettierPlugin from "prettier/plugins/yaml" import goPrettierPlugin from "@/common/prettier/plugins/go/go.mjs" -import sqlPrettierPlugin from "@/common/prettier/plugins/sql/sql" +import sqlPrettierPlugin from "@/common/prettier/plugins/sql" import phpPrettierPlugin from "@/common/prettier/plugins/php" import javaPrettierPlugin from "@/common/prettier/plugins/java" import xmlPrettierPlugin from "@prettier/plugin-xml" @@ -115,14 +115,23 @@ export const LANGUAGES: LanguageInfo[] = [ plugins: [xmlPrettierPlugin] }), new LanguageInfo("cpp", "C++", cppLanguage.parser, ["cpp", "c"], { - parser: "clang", - plugins: [clangPrettierPlugin] + parser: "clang-format", + plugins: [clangPrettierPlugin], + options: { + filename: "index.cpp" + } }), new LanguageInfo("rs", "Rust", rustLanguage.parser, ["rs"], { parser: "jinx-rust", plugins: [rustPrettierPlugin] }), - new LanguageInfo("cs", "C#", StreamLanguage.define(csharp).parser, ["cs"]), + new LanguageInfo("cs", "C#", StreamLanguage.define(csharp).parser, ["cs"],{ + parser: "clang-format", + plugins: [clangPrettierPlugin], + options: { + filename: "index.cs" + } + }), new LanguageInfo("rb", "Ruby", StreamLanguage.define(ruby).parser, ["rb"]), new LanguageInfo("sh", "Shell", StreamLanguage.define(shell).parser, ["sh", "bat"], { parser: "sh",