add 添加 eslint 和 prettier

update UI 库由 tDesign 改为 Ant Design Vue(主要是因为前者和 Vite 热更新不兼容)
pull/3/head
yupi 2 years ago
parent 45d17f1e1a
commit b41bea585a

@ -0,0 +1,17 @@
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: ["plugin:vue/essential", "plugin:prettier/recommended"],
parserOptions: {
ecmaVersion: "latest",
parser: "@typescript-eslint/parser",
sourceType: "module",
},
plugins: ["vue", "@typescript-eslint", "prettier"],
rules: {
"prettier/prettier": "error",
},
};

1
.gitignore vendored

@ -1,6 +1,7 @@
# Logs
logs
*.log
package-lock.json
npm-debug.log*
yarn-debug.log*
yarn-error.log*

@ -1,20 +1,32 @@
{
"name": "sql-generator",
"private": true,
"version": "0.0.0",
"version": "0.0.1",
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"preview": "vite preview"
},
"dependencies": {
"@ant-design/icons-vue": "^6.1.0",
"ant-design-vue": "^3.2.3",
"monaco-editor": "^0.33.0",
"sql-formatter": "^4.0.2",
"tdesign-vue-next": "^0.14.1",
"vue": "^3.2.25"
},
"devDependencies": {
"@typescript-eslint/eslint-plugin": "^5.23.0",
"@typescript-eslint/parser": "^5.23.0",
"@vitejs/plugin-vue": "^2.3.1",
"eslint": "^8.15.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-standard": "^17.0.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-n": "^15.2.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-promise": "^6.0.0",
"eslint-plugin-vue": "^8.7.1",
"prettier": "2.6.2",
"typescript": "^4.5.4",
"vite": "^2.9.7",
"vue-tsc": "^0.34.7"

@ -1,73 +1,83 @@
<script setup lang="ts">
import {doGenerateSQL} from "./generator";
import {onMounted, ref, toRaw} from "vue";
import { doGenerateSQL } from "./generator";
import { onMounted, ref, toRaw } from "vue";
import * as monaco from "monaco-editor";
import IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
import {format} from "sql-formatter";
import { format } from "sql-formatter";
import { GithubOutlined } from "@ant-design/icons-vue";
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker'
import jsonWorker from 'monaco-editor/esm/vs/language/json/json.worker?worker'
import cssWorker from 'monaco-editor/esm/vs/language/css/css.worker?worker'
import htmlWorker from 'monaco-editor/esm/vs/language/html/html.worker?worker'
import tsWorker from 'monaco-editor/esm/vs/language/typescript/ts.worker?worker'
import EditorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker";
import JsonWorker from "monaco-editor/esm/vs/language/json/json.worker?worker";
import CssWorker from "monaco-editor/esm/vs/language/css/css.worker?worker";
import HtmlWorker from "monaco-editor/esm/vs/language/html/html.worker?worker";
import TsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker";
// eslint-disable-next-line no-undef
import IStandaloneCodeEditor = monaco.editor.IStandaloneCodeEditor;
// @ts-ignore
(self as any).MonacoEnvironment = {
getWorker(_: any, label: any) {
if (label === 'json') {
return new jsonWorker()
if (label === "json") {
return new JsonWorker();
}
if (label === 'css' || label === 'scss' || label === 'less') {
return new cssWorker()
if (label === "css" || label === "scss" || label === "less") {
return new CssWorker();
}
if (label === 'html' || label === 'handlebars' || label === 'razor') {
return new htmlWorker()
if (label === "html" || label === "handlebars" || label === "razor") {
return new HtmlWorker();
}
if (label === 'typescript' || label === 'javascript') {
return new tsWorker()
if (label === "typescript" || label === "javascript") {
return new TsWorker();
}
return new editorWorker()
}
}
return new EditorWorker();
},
};
const initTreeNode = {
label: "main",
sql: "",
children: [],
};
const inputEditor = ref<IStandaloneCodeEditor>();
const outputEditor = ref<IStandaloneCodeEditor>();
const inputContainer = ref<HTMLElement>();
const outputContainer = ref<HTMLElement>();
const treeNode = ref<InvokeTreeNode>({ ...initTreeNode });
const getSQL = () => {
if (inputEditor.value && outputEditor.value) {
const inputJSON = JSON.parse(toRaw(inputEditor.value).getValue());
let result = format(doGenerateSQL(inputJSON));
treeNode.value = { ...initTreeNode };
const sqlResult = doGenerateSQL(inputJSON, treeNode.value);
let result = format(sqlResult);
//
result = result.replaceAll("{ {", "{{")
result = result.replaceAll("} }", "}}")
result = result.replaceAll("{ {", "{{");
result = result.replaceAll("} }", "}}");
toRaw(outputEditor.value).setValue(result);
console.log(treeNode.value);
}
}
const getInvokeTree = () => {
};
}
const getInvokeTree = () => {};
const initJSONValue = "{\n" +
" \"main\": {\n" +
" \"sql\": \"select * from @union_all_layer(分区 = 2021) where 分区 = #{分区}\",\n" +
" \"params\": {\n" +
" \"分区\": 2022\n" +
" }\n" +
" },\n" +
" \"union_all_layer\": {\n" +
" \"sql\": \"select * from xx where 分区 = #{分区}\"\n" +
" }\n" +
"}";
const initJSONValue =
"{\n" +
' "main": {\n' +
' "sql": "select * from @union_all_layer(分区 = 2021) where 分区 = #{分区}",\n' +
' "params": {\n' +
' "分区": 2022\n' +
" }\n" +
" },\n" +
' "union_all_layer": {\n' +
' "sql": "select * from xx where 分区 = #{分区}"\n' +
" }\n" +
"}";
onMounted(() => {
if (inputContainer.value) {
inputEditor.value = monaco.editor.create(inputContainer.value, {
value: localStorage.getItem('draft') ?? initJSONValue,
language: 'json',
theme: 'vs-dark',
value: localStorage.getItem("draft") ?? initJSONValue,
language: "json",
theme: "vs-dark",
formatOnPaste: true,
fontSize: 16,
minimap: {
@ -76,54 +86,73 @@ onMounted(() => {
});
setInterval(() => {
if (inputEditor.value) {
localStorage.setItem('draft', toRaw(inputEditor.value).getValue());
localStorage.setItem("draft", toRaw(inputEditor.value).getValue());
}
}, 3000)
}, 3000);
}
if (outputContainer.value) {
outputEditor.value = monaco.editor.create(outputContainer.value, {
value: "",
language: 'sql',
theme: 'vs-dark',
language: "sql",
theme: "vs-dark",
formatOnPaste: true,
fontSize: 16,
minimap: {
enabled: false,
},
});
getSQL();
}
});
</script>
<template>
<h1>
SQL 生成器 - JSON 来写 SQL
<div style="float: right">
<t-button size="large" theme="primary" @click="getSQL" > 生成 SQL</t-button>
<t-divider theme="vertical" />
<t-button size="large" theme="default" @click="getInvokeTree"> </t-button>
</div>
<t-tree :data="[]" activable hover />
</h1>
<t-row :gutter="24">
<t-col :xs="12" :sm="6">
<div id="inputContainer" ref="inputContainer" style="height: 80vh; max-width: 100%"/>
</t-col>
<t-col :xs="12" :sm="6">
<div id="outputContainer" ref="outputContainer" style="height: 80vh; max-width: 100%"/>
</t-col>
</t-row>
<br/>
<div>
yupi你能体会手写 1500 SQL牵一发而动全身的恐惧么
<a-row justify="space-between" align="middle" :gutter="[0, 16]">
<h1 style="margin-bottom: 0">🔨 结构化 SQL 生成器</h1>
<div>使用 JSON 来编写 SQL告别重复代码点击查看文档</div>
<a-space size="large">
<a-button size="large" type="primary" @click="getSQL">
生成 SQL
</a-button>
<a-button size="large" type="default" @click="getInvokeTree">
查看调用树
</a-button>
</a-space>
</a-row>
<div style="margin-top: 16px" />
<a-row :gutter="[16, 16]">
<a-col :sm="24" :md="12">
<div
id="inputContainer"
ref="inputContainer"
style="height: 80vh; max-width: 100%"
/>
</a-col>
<a-col :sm="24" :md="12">
<div
id="outputContainer"
ref="outputContainer"
style="height: 80vh; max-width: 100%"
/>
</a-col>
</a-row>
<br />
<div>yupi你能体会手写一句 3000 行的 SQL牵一发而动全身的恐惧么</div>
<a-row justify="center">
<a-space>
作者<a href="https://github.com/liyupi" target="_blank">鱼皮</a>
<a-divider type="vertical" />
<a href="https://github.com/liyupi/sql-generator" target="_blank">
<github-outlined />
项目已开源欢迎 star
</a>
</a-space>
</a-row>
</div>
</template>
<style>
#app {
padding: 0 25px;
padding: 20px;
}
</style>
</style>

@ -1,10 +1,7 @@
import { createApp } from 'vue';
import TDesign from 'tdesign-vue-next';
import App from './app.vue';
// 引入组件库全局样式资源
import 'tdesign-vue-next/es/style/index.css';
import { createApp } from "vue";
import App from "./App.vue";
import Antd from "ant-design-vue";
import "ant-design-vue/dist/antd.css";
const app = createApp(App);
app.use(TDesign);
app.mount('#app');
app.use(Antd).mount("#app");

@ -10,9 +10,21 @@
"resolveJsonModule": true,
"isolatedModules": true,
"esModuleInterop": true,
"lib": ["esnext", "dom"],
"lib": [
"esnext",
"dom"
],
"skipLibCheck": true
},
"include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.tsx", "src/**/*.vue"],
"references": [{ "path": "./tsconfig.node.json" }]
"include": [
"src/**/*.ts",
"src/**/*.d.ts",
"src/**/*.tsx",
"src/**/*.vue"
],
"references": [
{
"path": "./tsconfig.node.json"
}
]
}

@ -4,5 +4,7 @@
"module": "esnext",
"moduleResolution": "node"
},
"include": ["vite.config.ts"]
"include": [
"vite.config.ts"
]
}

@ -1,7 +1,11 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()]
})
server: {
open: true,
hmr: true,
},
plugins: [vue()],
});

Loading…
Cancel
Save