chore: upgrade frontend tooling and speed up checks
This commit is contained in:
parent
cc74fabad7
commit
e67894bea7
|
|
@ -33,14 +33,8 @@ jobs:
|
|||
- name: Install frontend dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Frontend format check
|
||||
run: npx oxfmt --check "apps/desktop/src/**/*.{ts,vue}"
|
||||
|
||||
- name: TypeScript check
|
||||
run: npx vue-tsc --noEmit --project apps/desktop/tsconfig.json
|
||||
|
||||
- name: Frontend tests
|
||||
run: pnpm test
|
||||
- name: Frontend check
|
||||
run: pnpm check
|
||||
|
||||
- name: Node package tests
|
||||
run: pnpm test:packages
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
npx lint-staged
|
||||
pnpm exec lint-staged
|
||||
|
||||
# Only format and re-add Rust files that are already staged
|
||||
TOPLEVEL=$(git rev-parse --show-toplevel)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { ref, computed, watch, onMounted, onUnmounted, nextTick, defineAsyncComponent } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import { ChevronsRight } from "lucide-vue-next";
|
||||
import { ChevronsRight } from "@lucide/vue";
|
||||
import { TooltipProvider } from "@/components/ui/tooltip";
|
||||
import AppToolbar from "@/components/layout/AppToolbar.vue";
|
||||
import AppTabBar from "@/components/layout/AppTabBar.vue";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { ref } from "vue";
|
|||
import { useI18n } from "vue-i18n";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Lock, Loader2, ShieldCheck } from "lucide-vue-next";
|
||||
import { Lock, Loader2, ShieldCheck } from "@lucide/vue";
|
||||
import AppLogo from "@/components/icons/AppLogo.vue";
|
||||
|
||||
const props = withDefaults(
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import { CanvasRenderer } from "echarts/renderers";
|
|||
import { LineChart, BarChart, PieChart } from "echarts/charts";
|
||||
import { GridComponent, TooltipComponent, LegendComponent } from "echarts/components";
|
||||
import VChart from "vue-echarts";
|
||||
import { BarChart3 } from "lucide-vue-next";
|
||||
import { BarChart3 } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import type { QueryResult } from "@/types/database";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Lock } from "lucide-vue-next";
|
||||
import { Lock } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, onUnmounted, computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { FolderOpen, Trash2, Download, RotateCcw, Loader2, RefreshCw, Check, Clock3, FileUp } from "lucide-vue-next";
|
||||
import { FolderOpen, Trash2, Download, RotateCcw, Loader2, RefreshCw, Check, Clock3, FileUp } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ import {
|
|||
Search,
|
||||
ShieldCheck,
|
||||
Trash2,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
|
||||
type DbOption = { value: string; label: string };
|
||||
type DbCategory = { key: string; title: string; options: DbOption[] };
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AlertTriangle, X } from "lucide-vue-next";
|
||||
import { AlertTriangle, X } from "@lucide/vue";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import {
|
|||
Table2,
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import {
|
|||
Loader2,
|
||||
Play,
|
||||
Square,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
|
||||
type CompareColumn = ColumnInfo;
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import type { TableDiff, TableSchemaDetail } from "@/lib/schemaDiff";
|
|||
import type { TableInfo } from "@/types/database";
|
||||
import { sqlMetadataRefreshTarget } from "@/lib/sqlMetadataRefresh";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { Loader2, Copy, Play, GitCompareArrows, ArrowLeftRight } from "lucide-vue-next";
|
||||
import { Loader2, Copy, Play, GitCompareArrows, ArrowLeftRight } from "@lucide/vue";
|
||||
import { useSqlHighlighter } from "@/composables/useSqlHighlighter";
|
||||
|
||||
interface SelectableTableDiff extends TableDiff {
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ import {
|
|||
X,
|
||||
Zap,
|
||||
TestTube,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { X, Copy } from "lucide-vue-next";
|
||||
import { X, Copy } from "@lucide/vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AlertTriangle } from "lucide-vue-next";
|
||||
import { AlertTriangle } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { useSqlHighlighter } from "@/composables/useSqlHighlighter";
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {
|
|||
replaceNext as cmReplaceNext,
|
||||
replaceAll as cmReplaceAll,
|
||||
} from "@codemirror/search";
|
||||
import { ChevronUp, ChevronDown, ChevronRight, X } from "lucide-vue-next";
|
||||
import { ChevronUp, ChevronDown, ChevronRight, X } from "@lucide/vue";
|
||||
|
||||
const props = defineProps<{
|
||||
view: EditorView | null;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ import {
|
|||
Trash2,
|
||||
Upload,
|
||||
X,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, onMounted, onBeforeUnmount, onActivated, onDeactivated, watch, shallowRef, computed } from "vue";
|
||||
import { Play, Copy, TextSelect } from "lucide-vue-next";
|
||||
import { Play, Copy, TextSelect } from "@lucide/vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import type { CompletionContext } from "@codemirror/autocomplete";
|
||||
import type { EditorView as EditorViewType } from "@codemirror/view";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { ref, computed, onMounted } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { useSqlHighlighter } from "@/composables/useSqlHighlighter";
|
||||
import { Clock, Copy, Database, RotateCcw, Search, Sparkles, Trash2, X } from "lucide-vue-next";
|
||||
import { Clock, Copy, Database, RotateCcw, Search, Sparkles, Trash2, X } from "@lucide/vue";
|
||||
import { RecycleScroller } from "vue-virtual-scroller";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { ChevronRight } from "lucide-vue-next";
|
||||
import { ChevronRight } from "@lucide/vue";
|
||||
import type { ExplainPlanNode } from "@/lib/explainPlan";
|
||||
|
||||
defineProps<{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AlertCircle, Braces, GitBranch, Table2 } from "lucide-vue-next";
|
||||
import { AlertCircle, Braces, GitBranch, Table2 } from "@lucide/vue";
|
||||
import type { ParsedExplainPlan, ExplainPlanNode } from "@/lib/explainPlan";
|
||||
import { flattenExplainPlanNodes } from "@/lib/explainPlan";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { buildSelectedTablesPayload } from "@/lib/databaseExportSelection";
|
|||
import { isTauriRuntime } from "@/lib/tauriRuntime";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Download, Square, CheckSquare, Search, X } from "lucide-vue-next";
|
||||
import { Download, Square, CheckSquare, Search, X } from "@lucide/vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { toast } = useToast();
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import { computed } from "vue";
|
|||
import { useI18n } from "vue-i18n";
|
||||
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter } from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Loader2, CheckCircle2, XCircle, AlertCircle, X } from "lucide-vue-next";
|
||||
import { Loader2, CheckCircle2, XCircle, AlertCircle, X } from "@lucide/vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const open = defineModel<boolean>("open", { default: false });
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ import {
|
|||
PanelBottom,
|
||||
PanelRight,
|
||||
TableProperties,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import CustomContextMenu, { type ContextMenuItem } from "@/components/ui/CustomContextMenu.vue";
|
||||
import {
|
||||
|
|
@ -1627,7 +1627,14 @@ interface RenderedGridColumn {
|
|||
name: string;
|
||||
}
|
||||
|
||||
const horizontalColumnWindow = computed(() => {
|
||||
interface HorizontalColumnWindow {
|
||||
start: number;
|
||||
end: number;
|
||||
beforeWidth: number;
|
||||
afterWidth: number;
|
||||
}
|
||||
|
||||
function getHorizontalColumnWindow(): HorizontalColumnWindow {
|
||||
const widths = renderedColumnWidths.value;
|
||||
const offsets = renderedColumnOffsets.value;
|
||||
const totalColumns = visibleColumnIndexes.value.length;
|
||||
|
|
@ -1666,7 +1673,9 @@ const horizontalColumnWindow = computed(() => {
|
|||
beforeWidth: offset,
|
||||
afterWidth: Math.max(0, columnsWidth - visibleWidth),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const horizontalColumnWindow = computed(getHorizontalColumnWindow);
|
||||
|
||||
const renderedGridColumns = computed<RenderedGridColumn[]>(() => {
|
||||
const window = horizontalColumnWindow.value;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { ExternalLink, Maximize2, X, ZoomIn, ZoomOut } from "lucide-vue-next";
|
||||
import { ExternalLink, Maximize2, X, ZoomIn, ZoomOut } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogTitle } from "@/components/ui/dialog";
|
||||
import { imagePreviewFitScale, imagePreviewTransform, nextImagePreviewScale } from "@/lib/imagePreviewViewer";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, onMounted, ref } from "vue";
|
||||
import type { FocusOutsideEvent, PointerDownOutsideEvent } from "reka-ui";
|
||||
import { CalendarClock, ChevronDown, ChevronUp, CircleSlash } from "lucide-vue-next";
|
||||
import { CalendarClock, ChevronDown, ChevronUp, CircleSlash } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
import { formatTemporalInputValue, type TemporalCellEditorKind } from "@/lib/dataGridTemporalEditor";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { Settings2 } from "lucide-vue-next";
|
||||
import { Settings2 } from "@lucide/vue";
|
||||
import type { AiProvider } from "@/stores/settingsStore";
|
||||
import { useTheme } from "@/composables/useTheme";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { Database } from "lucide-vue-next";
|
||||
import { Database } from "@lucide/vue";
|
||||
|
||||
const props = defineProps<{
|
||||
dbType: string;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import { Button } from "@/components/ui/button";
|
|||
import { Input } from "@/components/ui/input";
|
||||
import { Label } from "@/components/ui/label";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { Check, FileUp, Loader2, Square, Upload, X } from "lucide-vue-next";
|
||||
import { Check, FileUp, Loader2, Square, Upload, X } from "@lucide/vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useToast } from "@/composables/useToast";
|
||||
import { autoMapImportColumns } from "@/lib/tableImport";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { computed, ref } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { translateBackendError } from "@/i18n/backend-errors";
|
||||
import { Upload, Download, FolderPlus, RefreshCw, ChevronsLeft } from "lucide-vue-next";
|
||||
import { Upload, Download, FolderPlus, RefreshCw, ChevronsLeft } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
|
||||
import LightDropdown from "@/components/ui/LightDropdown.vue";
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {
|
|||
Pencil,
|
||||
Package,
|
||||
Check,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import CustomContextMenu, { type ContextMenuItem } from "@/components/ui/CustomContextMenu.vue";
|
||||
import LightDropdown from "@/components/ui/LightDropdown.vue";
|
||||
import { Tooltip, TooltipTrigger, TooltipContent } from "@/components/ui/tooltip";
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import {
|
|||
Settings,
|
||||
CloudDownload,
|
||||
Package,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
|
||||
import LightDropdown from "@/components/ui/LightDropdown.vue";
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
ChevronUp,
|
||||
RefreshCcw,
|
||||
Wrench,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
import "splitpanes/dist/splitpanes.css";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import {
|
|||
Save,
|
||||
FolderOpen,
|
||||
Layers,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { SearchableSelect } from "@/components/ui/searchable-select";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Loader2 } from "lucide-vue-next";
|
||||
import { Loader2 } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import type { UpdateInfo } from "@/lib/api";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { FilePlus2, Plus, History, Upload, Database, Search, ShieldCheck, Sparkles } from "lucide-vue-next";
|
||||
import { FilePlus2, Plus, History, Upload, Database, Search, ShieldCheck, Sparkles } from "@lucide/vue";
|
||||
import DatabaseIcon from "@/components/icons/DatabaseIcon.vue";
|
||||
import {
|
||||
connectionDriverLabel,
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
<script setup lang="ts">
|
||||
import { Minus, Square, Copy, X } from "lucide-vue-next";
|
||||
import { Minus, Square, Copy, X } from "@lucide/vue";
|
||||
|
||||
defineProps<{
|
||||
isMaximized: boolean;
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import {
|
|||
Search,
|
||||
SearchX,
|
||||
X,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Dialog, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle } from "@/components/ui/dialog";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { computed, ref } from "vue";
|
||||
import { uuid } from "@/lib/utils";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Plus, Trash2 } from "lucide-vue-next";
|
||||
import { Plus, Trash2 } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import DangerConfirmDialog from "@/components/editor/DangerConfirmDialog.vue";
|
||||
import type { EditNode, EditNodeKind } from "@/types/editor";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { computed, ref, onMounted } from "vue";
|
||||
import { uuid } from "@/lib/utils";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { RefreshCw, Trash2, Plus, Save, ChevronLeft, ChevronRight, Table2, Braces, X } from "lucide-vue-next";
|
||||
import { RefreshCw, Trash2, Plus, Save, ChevronLeft, ChevronRight, Table2, Braces, X } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import DangerConfirmDialog from "@/components/editor/DangerConfirmDialog.vue";
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import {
|
|||
TerminalSquare,
|
||||
Trash2,
|
||||
X,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { CircleHelp, Loader2 } from "lucide-vue-next";
|
||||
import { CircleHelp, Loader2 } from "@lucide/vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, defineComponent, h, ref, type VNodeChild } from "vue";
|
||||
import { ChevronDown, ChevronRight } from "lucide-vue-next";
|
||||
import { ChevronDown, ChevronRight } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
defineOptions({ name: "RedisJsonTree" });
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import {
|
|||
KeyRound,
|
||||
TerminalSquare,
|
||||
Asterisk,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import { RecycleScroller } from "vue-virtual-scroller";
|
||||
import "vue-virtual-scroller/dist/vue-virtual-scroller.css";
|
||||
import { Splitpanes, Pane } from "splitpanes";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { computed, ref, onBeforeUnmount, onMounted } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { DynamicScroller, DynamicScrollerItem, RecycleScroller } from "vue-virtual-scroller";
|
||||
import { Braces, Copy, Eye, FileText, Trash2, Save, RefreshCw, Plus, Loader2, Pencil, WrapText } from "lucide-vue-next";
|
||||
import { Braces, Copy, Eye, FileText, Trash2, Save, RefreshCw, Plus, Loader2, Pencil, WrapText } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
import { computed, ref, watch } from "vue";
|
||||
import { uuid } from "@/lib/utils";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { AlertCircle, Loader2, Search, Square, Table2 } from "lucide-vue-next";
|
||||
import { AlertCircle, Loader2, Search, Square, Table2 } from "@lucide/vue";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogFooter, DialogHeader, DialogScrollContent, DialogTitle } from "@/components/ui/dialog";
|
||||
|
|
|
|||
|
|
@ -1,18 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, computed, nextTick, watch, type Component } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import {
|
||||
Search,
|
||||
X,
|
||||
ListFilter,
|
||||
Crosshair,
|
||||
Server,
|
||||
Database,
|
||||
FolderTree,
|
||||
Table2,
|
||||
Eye,
|
||||
RotateCcw,
|
||||
} from "lucide-vue-next";
|
||||
import { Search, X, ListFilter, Crosshair, Server, Database, FolderTree, Table2, Eye, RotateCcw } from "@lucide/vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
import { useSettingsStore } from "@/stores/settingsStore";
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ import {
|
|||
ListFilter,
|
||||
Package,
|
||||
Clipboard,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import CustomContextMenu, { type ContextMenuItem } from "@/components/ui/CustomContextMenu.vue";
|
||||
import { useConnectionStore } from "@/stores/connectionStore";
|
||||
import { useQueryStore } from "@/stores/queryStore";
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, ref, watch } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { CheckSquare, Loader2, Search, Square } from "lucide-vue-next";
|
||||
import { CheckSquare, Loader2, Search, Square } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||
import { Input } from "@/components/ui/input";
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ import {
|
|||
type SqlFileProgress,
|
||||
type SqlFileStatus,
|
||||
} from "@/lib/api";
|
||||
import { Check, CheckSquare, FileCode, FolderOpen, Loader2, Play, Square, X } from "lucide-vue-next";
|
||||
import { Check, CheckSquare, FileCode, FolderOpen, Loader2, Play, Square, X } from "@lucide/vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const { toast } = useToast();
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ import {
|
|||
SlidersHorizontal,
|
||||
Trash2,
|
||||
X,
|
||||
} from "lucide-vue-next";
|
||||
} from "@lucide/vue";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuCheckboxItem,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import type { TransferProgress, TransferMode } from "@/lib/api";
|
|||
import type { DatabaseType } from "@/types/database";
|
||||
import { isSchemaAware, supportsTransfer } from "@/lib/databaseCapabilities";
|
||||
import { nextTransferTerminalState } from "@/lib/transferProgressState";
|
||||
import { ArrowRightLeft, Check, X, Loader2, Square, CheckSquare } from "lucide-vue-next";
|
||||
import { ArrowRightLeft, Check, X, Loader2, Square, CheckSquare } from "@lucide/vue";
|
||||
|
||||
const { t } = useI18n();
|
||||
const open = defineModel<boolean>("open", { default: false });
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { ref, watch, onBeforeUnmount, nextTick, type Component } from "vue";
|
||||
import { ChevronRight } from "lucide-vue-next";
|
||||
import { ChevronRight } from "@lucide/vue";
|
||||
|
||||
export interface ContextMenuItem {
|
||||
label: string;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, onBeforeUnmount, ref, type Component } from "vue";
|
||||
import { Check, ChevronDown } from "lucide-vue-next";
|
||||
import { Check, ChevronDown } from "@lucide/vue";
|
||||
|
||||
export interface LightDropdownItem {
|
||||
label: string;
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { ContextMenuCheckboxItemEmits, ContextMenuCheckboxItemProps } from
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { CheckIcon } from "lucide-vue-next";
|
||||
import { CheckIcon } from "@lucide/vue";
|
||||
import { ContextMenuCheckboxItem, ContextMenuItemIndicator, useForwardPropsEmits } from "reka-ui";
|
||||
import { shouldSuppressRepeatedActivation, suppressEvent, type ActionActivationGuard } from "@/lib/actionActivation";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { ContextMenuRadioItemEmits, ContextMenuRadioItemProps } from "reka-
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { CheckIcon } from "lucide-vue-next";
|
||||
import { CheckIcon } from "@lucide/vue";
|
||||
import { ContextMenuItemIndicator, ContextMenuRadioItem, useForwardPropsEmits } from "reka-ui";
|
||||
import { shouldSuppressRepeatedActivation, suppressEvent, type ActionActivationGuard } from "@/lib/actionActivation";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { ContextMenuSubTriggerProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { ChevronRightIcon } from "lucide-vue-next";
|
||||
import { ChevronRightIcon } from "@lucide/vue";
|
||||
import { ContextMenuSubTrigger, useForwardProps } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { DialogContentEmits, DialogContentProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { XIcon } from "lucide-vue-next";
|
||||
import { XIcon } from "@lucide/vue";
|
||||
import {
|
||||
DialogClose,
|
||||
DialogContent,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { DialogContentEmits, DialogContentProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { XIcon } from "lucide-vue-next";
|
||||
import { XIcon } from "@lucide/vue";
|
||||
import { DialogClose, DialogContent, DialogOverlay, DialogPortal, useForwardPropsEmits } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { DropdownMenuCheckboxItemEmits, DropdownMenuCheckboxItemProps } fro
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { CheckIcon } from "lucide-vue-next";
|
||||
import { CheckIcon } from "@lucide/vue";
|
||||
import { DropdownMenuCheckboxItem, DropdownMenuItemIndicator, useForwardPropsEmits } from "reka-ui";
|
||||
import { shouldSuppressRepeatedActivation, suppressEvent, type ActionActivationGuard } from "@/lib/actionActivation";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { DropdownMenuRadioItemEmits, DropdownMenuRadioItemProps } from "rek
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { CheckIcon } from "lucide-vue-next";
|
||||
import { CheckIcon } from "@lucide/vue";
|
||||
import { DropdownMenuItemIndicator, DropdownMenuRadioItem, useForwardPropsEmits } from "reka-ui";
|
||||
import { shouldSuppressRepeatedActivation, suppressEvent, type ActionActivationGuard } from "@/lib/actionActivation";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { DropdownMenuSubTriggerProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { ChevronRightIcon } from "lucide-vue-next";
|
||||
import { ChevronRightIcon } from "@lucide/vue";
|
||||
import { DropdownMenuSubTrigger, useForwardProps } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<script setup lang="ts">
|
||||
import { computed, nextTick, ref, watch } from "vue";
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { Check, ChevronDown, Search } from "lucide-vue-next";
|
||||
import { Check, ChevronDown, Search } from "@lucide/vue";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Input } from "@/components/ui/input";
|
||||
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { SelectItemProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { CheckIcon } from "lucide-vue-next";
|
||||
import { CheckIcon } from "@lucide/vue";
|
||||
import { SelectItem, SelectItemIndicator, SelectItemText, useForwardProps } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { SelectScrollDownButtonProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { ChevronDownIcon } from "lucide-vue-next";
|
||||
import { ChevronDownIcon } from "@lucide/vue";
|
||||
import { SelectScrollDownButton, useForwardProps } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { SelectScrollUpButtonProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { ChevronUpIcon } from "lucide-vue-next";
|
||||
import { ChevronUpIcon } from "@lucide/vue";
|
||||
import { SelectScrollUpButton, useForwardProps } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { SelectTriggerProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { ChevronDownIcon } from "lucide-vue-next";
|
||||
import { ChevronDownIcon } from "@lucide/vue";
|
||||
import { SelectIcon, SelectTrigger, useForwardProps } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ import type { DialogContentEmits, DialogContentProps } from "reka-ui";
|
|||
|
||||
import type { HTMLAttributes } from "vue";
|
||||
import { reactiveOmit } from "@vueuse/core";
|
||||
import { XIcon } from "lucide-vue-next";
|
||||
import { XIcon } from "@lucide/vue";
|
||||
import { DialogClose, DialogContent, DialogPortal, useForwardPropsEmits } from "reka-ui";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
|
|
|||
|
|
@ -21,6 +21,10 @@ const HEX_VALUE_RE = /^(?:0[xX]|\\x)([0-9a-fA-F\s]+)$/;
|
|||
const BINARY_TYPE_RE =
|
||||
/^(?:blob|tinyblob|mediumblob|longblob|bytea|bytes|binary|varbinary|image|raw|long\s+raw)(?:\b|\()/i;
|
||||
|
||||
function copyBytesForBlob(bytes: Uint8Array): Uint8Array<ArrayBuffer> {
|
||||
return new Uint8Array(bytes);
|
||||
}
|
||||
|
||||
export function parseBinaryCellHexValue(value: CellValue): Uint8Array | null {
|
||||
if (typeof value !== "string") return null;
|
||||
const match = value.trim().match(HEX_VALUE_RE);
|
||||
|
|
@ -105,7 +109,9 @@ export async function downloadBinaryCellPayload(
|
|||
return { kind: "saved", path };
|
||||
}
|
||||
|
||||
const blob = new Blob([payload.data], { type: payload.mimeType });
|
||||
const blob = new Blob([typeof payload.data === "string" ? payload.data : copyBytesForBlob(payload.data)], {
|
||||
type: payload.mimeType,
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
const a = document.createElement("a");
|
||||
a.href = url;
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export interface PlainConfigPayload {
|
|||
|
||||
const PBKDF2_ITERATIONS = 100_000;
|
||||
|
||||
async function deriveKey(passphrase: string, salt: Uint8Array): Promise<CryptoKey> {
|
||||
async function deriveKey(passphrase: string, salt: Uint8Array<ArrayBuffer>): Promise<CryptoKey> {
|
||||
const encoder = new TextEncoder();
|
||||
const baseKey = await crypto.subtle.importKey("raw", encoder.encode(passphrase), "PBKDF2", false, ["deriveKey"]);
|
||||
return crypto.subtle.deriveKey(
|
||||
|
|
@ -26,8 +26,8 @@ async function deriveKey(passphrase: string, salt: Uint8Array): Promise<CryptoKe
|
|||
);
|
||||
}
|
||||
|
||||
function toBase64(buffer: ArrayBuffer): string {
|
||||
const bytes = new Uint8Array(buffer);
|
||||
function toBase64(data: ArrayBuffer | Uint8Array<ArrayBuffer>): string {
|
||||
const bytes = data instanceof Uint8Array ? data : new Uint8Array(data);
|
||||
let binary = "";
|
||||
for (let i = 0; i < bytes.length; i++) {
|
||||
binary += String.fromCharCode(bytes[i]);
|
||||
|
|
@ -35,7 +35,7 @@ function toBase64(buffer: ArrayBuffer): string {
|
|||
return btoa(binary);
|
||||
}
|
||||
|
||||
function fromBase64(base64: string): Uint8Array {
|
||||
function fromBase64(base64: string): Uint8Array<ArrayBuffer> {
|
||||
const binary = atob(base64);
|
||||
const bytes = new Uint8Array(binary.length);
|
||||
for (let i = 0; i < binary.length; i++) {
|
||||
|
|
|
|||
|
|
@ -1188,7 +1188,7 @@ export async function exportQueryResultXlsx(
|
|||
rows,
|
||||
});
|
||||
const fileName = filePath.split(/[\\/]/).pop() || "export.xlsx";
|
||||
const blob = new Blob([workbook], {
|
||||
const blob = new Blob([new Uint8Array(workbook)], {
|
||||
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
||||
});
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
|
|
|||
|
|
@ -38,6 +38,22 @@ const STORAGE_KEY = "dbx-open-tabs";
|
|||
const ACTIVE_TAB_KEY = "dbx-active-tab";
|
||||
const ORACLE_LIKE_METADATA_TYPES = new Set<string>(["oracle", "dameng", "oceanbase-oracle"]);
|
||||
|
||||
async function withFrontendQueryTimeout<T>(promise: Promise<T>, timeoutSecs: number, message: string): Promise<T> {
|
||||
if (timeoutSecs === 0) return promise;
|
||||
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
try {
|
||||
return await Promise.race([
|
||||
promise,
|
||||
new Promise<never>((_, reject) => {
|
||||
timer = setTimeout(() => reject(new Error(message)), timeoutSecs * 1000);
|
||||
}),
|
||||
]);
|
||||
} finally {
|
||||
if (timer) clearTimeout(timer);
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeOracleLikeMetadataIdentifier(dbType: string, identifier: string | undefined, quoted?: boolean) {
|
||||
if (!identifier || quoted || !ORACLE_LIKE_METADATA_TYPES.has(dbType)) return identifier;
|
||||
return identifier.toUpperCase();
|
||||
|
|
@ -961,19 +977,12 @@ export const useQueryStore = defineStore("query", () => {
|
|||
executionId,
|
||||
executionOptions,
|
||||
);
|
||||
const results =
|
||||
queryTimeoutSecs === 0
|
||||
? await executionPromise
|
||||
: await Promise.race([
|
||||
executionPromise,
|
||||
new Promise<never>((_, reject) => {
|
||||
const frontendTimeoutSecs = Math.max(queryTimeoutSecs * 2, 60);
|
||||
setTimeout(
|
||||
() => reject(new Error(t("editor.queryTimeoutError", { seconds: frontendTimeoutSecs }))),
|
||||
frontendTimeoutSecs * 1000,
|
||||
);
|
||||
}),
|
||||
]);
|
||||
const frontendTimeoutSecs = Math.max(queryTimeoutSecs * 2, 60);
|
||||
const results = await withFrontendQueryTimeout(
|
||||
executionPromise,
|
||||
queryTimeoutSecs === 0 ? 0 : frontendTimeoutSecs,
|
||||
t("editor.queryTimeoutError", { seconds: frontendTimeoutSecs }),
|
||||
);
|
||||
console.info("[DBX][executeTabSql:execute-multi:done]", {
|
||||
traceId,
|
||||
resultCount: results.length,
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
declare module "vue-virtual-scroller" {
|
||||
import type { DefineComponent } from "vue";
|
||||
const VueVirtualScroller: any;
|
||||
export const RecycleScroller: DefineComponent<any, any, any>;
|
||||
export const DynamicScroller: DefineComponent<any, any, any>;
|
||||
export const DynamicScrollerItem: DefineComponent<any, any, any>;
|
||||
export const RecycleScroller: any;
|
||||
export const DynamicScroller: any;
|
||||
export const DynamicScrollerItem: any;
|
||||
export default VueVirtualScroller;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@
|
|||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"isolatedModules": true,
|
||||
"incremental": true,
|
||||
"tsBuildInfoFile": "../../node_modules/.cache/vue-tsc/desktop.tsbuildinfo",
|
||||
"moduleDetection": "force",
|
||||
"noEmit": true,
|
||||
"jsx": "preserve",
|
||||
|
|
@ -15,7 +17,6 @@
|
|||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,55 @@ import path from "path";
|
|||
|
||||
const host = process.env.TAURI_DEV_HOST;
|
||||
const isTauri = !!host || !!process.env.TAURI_ENV_ARCH;
|
||||
const manualChunks: Record<string, string[]> = {
|
||||
codemirror: [
|
||||
"codemirror",
|
||||
"@codemirror/lang-sql",
|
||||
"@codemirror/view",
|
||||
"@codemirror/state",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/commands",
|
||||
"@codemirror/theme-one-dark",
|
||||
],
|
||||
"sql-formatter": ["sql-formatter"],
|
||||
"vue-echarts": ["vue-echarts"],
|
||||
ui: ["reka-ui"],
|
||||
marked: ["marked"],
|
||||
};
|
||||
|
||||
function chunkNameForEchartsModule(id: string): string {
|
||||
const echartsPath = id.split("/node_modules/echarts/").pop() ?? "";
|
||||
|
||||
if (echartsPath === "charts.js" || echartsPath.startsWith("lib/chart/")) {
|
||||
return "echarts-charts";
|
||||
}
|
||||
|
||||
if (echartsPath === "components.js" || echartsPath.startsWith("lib/component/")) {
|
||||
return "echarts-components";
|
||||
}
|
||||
|
||||
if (echartsPath === "renderers.js" || echartsPath.startsWith("lib/renderer/")) {
|
||||
return "echarts-renderers";
|
||||
}
|
||||
|
||||
return "echarts-core";
|
||||
}
|
||||
|
||||
function chunkNameForModule(id: string): string | undefined {
|
||||
const normalizedId = id.replaceAll("\\", "/");
|
||||
|
||||
if (normalizedId.includes("/node_modules/echarts/")) {
|
||||
return chunkNameForEchartsModule(normalizedId);
|
||||
}
|
||||
|
||||
for (const [chunkName, packages] of Object.entries(manualChunks)) {
|
||||
if (packages.some((pkg) => normalizedId.includes(`/node_modules/${pkg}/`))) {
|
||||
return chunkName;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export default defineConfig(async () => ({
|
||||
root: __dirname,
|
||||
|
|
@ -20,20 +69,7 @@ export default defineConfig(async () => ({
|
|||
emptyOutDir: true,
|
||||
rollupOptions: {
|
||||
output: {
|
||||
manualChunks: {
|
||||
codemirror: [
|
||||
"codemirror",
|
||||
"@codemirror/lang-sql",
|
||||
"@codemirror/view",
|
||||
"@codemirror/state",
|
||||
"@codemirror/autocomplete",
|
||||
"@codemirror/commands",
|
||||
"@codemirror/theme-one-dark",
|
||||
],
|
||||
"sql-formatter": ["sql-formatter"],
|
||||
ui: ["reka-ui"],
|
||||
marked: ["marked"],
|
||||
},
|
||||
manualChunks: chunkNameForModule,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
|
|
|||
70
package.json
70
package.json
|
|
@ -16,8 +16,10 @@
|
|||
"test:packages": "pnpm --filter @dbx-app/node-core test && pnpm --filter @dbx-app/cli test && pnpm --filter @dbx-app/mcp-server test",
|
||||
"pack:packages": "rm -rf /tmp/dbx-pack-check && mkdir -p /tmp/dbx-pack-check && pnpm --filter @dbx-app/node-core pack --pack-destination /tmp/dbx-pack-check && pnpm --filter @dbx-app/cli pack --pack-destination /tmp/dbx-pack-check && pnpm --filter @dbx-app/mcp-server pack --pack-destination /tmp/dbx-pack-check",
|
||||
"publish:dry-run": "pnpm build:packages && pnpm pack:packages",
|
||||
"build": "vue-tsc --noEmit --project apps/desktop/tsconfig.json && vite build --config apps/desktop/vite.config.ts",
|
||||
"check": "oxfmt --check \"apps/desktop/src/**/*.{ts,vue}\" && pnpm lint && vue-tsc --noEmit --project apps/desktop/tsconfig.json && pnpm test",
|
||||
"typecheck": "vue-tsc --noEmit --project apps/desktop/tsconfig.json",
|
||||
"build": "vite build --config apps/desktop/vite.config.ts",
|
||||
"build:checked": "pnpm typecheck && pnpm build",
|
||||
"check": "node scripts/run-check.mjs",
|
||||
"lint": "oxlint --vue-plugin apps/desktop/src",
|
||||
"fmt": "oxfmt \"apps/desktop/src/**/*.{ts,vue}\"",
|
||||
"test": "tsx --tsconfig apps/desktop/tsconfig.json --test packages/app-tests/*.test.ts",
|
||||
|
|
@ -26,8 +28,8 @@
|
|||
"prepare": "husky"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.29.2",
|
||||
"@codemirror/autocomplete": "^6.20.1",
|
||||
"@babel/runtime": "^7.29.7",
|
||||
"@codemirror/autocomplete": "^6.20.2",
|
||||
"@codemirror/commands": "^6.10.3",
|
||||
"@codemirror/lang-json": "^6.0.2",
|
||||
"@codemirror/lang-sql": "^6.10.0",
|
||||
|
|
@ -35,7 +37,8 @@
|
|||
"@codemirror/search": "^6.7.0",
|
||||
"@codemirror/state": "^6.6.0",
|
||||
"@codemirror/theme-one-dark": "^6.1.3",
|
||||
"@codemirror/view": "^6.41.1",
|
||||
"@codemirror/view": "^6.43.0",
|
||||
"@lucide/vue": "1.17.0",
|
||||
"@tauri-apps/api": "^2.11.0",
|
||||
"@tauri-apps/plugin-clipboard-manager": "^2.3.2",
|
||||
"@tauri-apps/plugin-dialog": "^2.7.1",
|
||||
|
|
@ -43,49 +46,48 @@
|
|||
"@tauri-apps/plugin-process": "^2.3.1",
|
||||
"@tauri-apps/plugin-shell": "^2.3.5",
|
||||
"@tauri-apps/plugin-updater": "^2.10.1",
|
||||
"@uiw/codemirror-theme-duotone": "^4.25.9",
|
||||
"@uiw/codemirror-theme-material": "^4.25.9",
|
||||
"@uiw/codemirror-theme-nord": "^4.25.9",
|
||||
"@uiw/codemirror-theme-okaidia": "^4.25.9",
|
||||
"@uiw/codemirror-theme-vscode": "^4.25.9",
|
||||
"@uiw/codemirror-theme-xcode": "^4.25.9",
|
||||
"@uiw/codemirror-theme-duotone": "^4.25.10",
|
||||
"@uiw/codemirror-theme-material": "^4.25.10",
|
||||
"@uiw/codemirror-theme-nord": "^4.25.10",
|
||||
"@uiw/codemirror-theme-okaidia": "^4.25.10",
|
||||
"@uiw/codemirror-theme-vscode": "^4.25.10",
|
||||
"@uiw/codemirror-theme-xcode": "^4.25.10",
|
||||
"@vueuse/core": "^14.2.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
"clsx": "^2.1.1",
|
||||
"codemirror": "^6.0.2",
|
||||
"echarts": "^6.0.0",
|
||||
"lucide-vue-next": "^1.0.0",
|
||||
"marked": "^18.0.3",
|
||||
"echarts": "^6.1.0",
|
||||
"marked": "^18.0.4",
|
||||
"pinia": "^3.0.0",
|
||||
"reka-ui": "^2.9.8",
|
||||
"shadcn-vue": "^2.7.3",
|
||||
"shiki": "^4.1.0",
|
||||
"splitpanes": "^4.0.4",
|
||||
"sql-formatter": "^15.7.3",
|
||||
"tailwind-merge": "^3.5.0",
|
||||
"shiki": "^4.2.0",
|
||||
"splitpanes": "^4.1.2",
|
||||
"sql-formatter": "^15.8.0",
|
||||
"tailwind-merge": "^3.6.0",
|
||||
"tw-animate-css": "^1.4.0",
|
||||
"vue": "^3.5.0",
|
||||
"vue": "^3.5.35",
|
||||
"vue-echarts": "^8.0.1",
|
||||
"vue-i18n": "^11.4.0",
|
||||
"vue-virtual-scroller": "^3.0.1"
|
||||
"vue-i18n": "^11.4.4",
|
||||
"vue-virtual-scroller": "^3.0.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@oxfmt/binding-darwin-arm64": "0.47.0",
|
||||
"@oxlint/binding-darwin-arm64": "1.62.0",
|
||||
"@tailwindcss/vite": "^4.2.4",
|
||||
"@tauri-apps/cli": "^2.11.0",
|
||||
"@types/node": "^25.6.0",
|
||||
"@oxfmt/binding-darwin-arm64": "0.53.0",
|
||||
"@oxlint/binding-darwin-arm64": "1.68.0",
|
||||
"@tailwindcss/vite": "^4.3.0",
|
||||
"@tauri-apps/cli": "^2.11.2",
|
||||
"@types/node": "^25.9.1",
|
||||
"@types/splitpanes": "^2.2.6",
|
||||
"@vitejs/plugin-vue": "^5.2.0",
|
||||
"@vitejs/plugin-vue": "^6.0.7",
|
||||
"husky": "^9.1.7",
|
||||
"lint-staged": "^16.4.0",
|
||||
"oxfmt": "0.47.0",
|
||||
"oxlint": "^1.62.0",
|
||||
"tailwindcss": "^4.2.4",
|
||||
"tsx": "^4.21.0",
|
||||
"typescript": "~5.6.0",
|
||||
"vite": "^6.0.0",
|
||||
"vue-tsc": "^2.2.0"
|
||||
"oxfmt": "0.53.0",
|
||||
"oxlint": "^1.68.0",
|
||||
"tailwindcss": "^4.3.0",
|
||||
"tsx": "^4.22.4",
|
||||
"typescript": "~6.0.3",
|
||||
"vite": "^8.0.16",
|
||||
"vue-tsc": "^3.3.3"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
|
|
|
|||
2109
pnpm-lock.yaml
2109
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,85 @@
|
|||
import { spawn } from "node:child_process";
|
||||
import { performance } from "node:perf_hooks";
|
||||
|
||||
const tasks = [
|
||||
{
|
||||
name: "format",
|
||||
command: "oxfmt",
|
||||
args: ["--check", "apps/desktop/src/**/*.{ts,vue}"],
|
||||
},
|
||||
{
|
||||
name: "lint",
|
||||
command: "oxlint",
|
||||
args: ["--vue-plugin", "apps/desktop/src"],
|
||||
},
|
||||
{
|
||||
name: "typecheck",
|
||||
command: "vue-tsc",
|
||||
args: ["--noEmit", "--project", "apps/desktop/tsconfig.json"],
|
||||
},
|
||||
{
|
||||
name: "test",
|
||||
command: "tsx",
|
||||
args: ["--tsconfig", "apps/desktop/tsconfig.json", "--test", "packages/app-tests/*.test.ts"],
|
||||
},
|
||||
];
|
||||
|
||||
function runTask(task) {
|
||||
const startedAt = performance.now();
|
||||
const child = spawn(task.command, task.args, {
|
||||
cwd: process.cwd(),
|
||||
env: process.env,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
});
|
||||
const stdout = [];
|
||||
const stderr = [];
|
||||
|
||||
child.stdout.on("data", (chunk) => stdout.push(chunk));
|
||||
child.stderr.on("data", (chunk) => stderr.push(chunk));
|
||||
|
||||
return new Promise((resolve) => {
|
||||
child.on("error", (error) => {
|
||||
resolve({
|
||||
...task,
|
||||
code: 1,
|
||||
durationMs: performance.now() - startedAt,
|
||||
output: "",
|
||||
errorOutput: error.stack ?? String(error),
|
||||
});
|
||||
});
|
||||
|
||||
child.on("close", (code) => {
|
||||
resolve({
|
||||
...task,
|
||||
code,
|
||||
durationMs: performance.now() - startedAt,
|
||||
output: Buffer.concat(stdout).toString(),
|
||||
errorOutput: Buffer.concat(stderr).toString(),
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
const results = await Promise.all(tasks.map(runTask));
|
||||
|
||||
for (const result of results) {
|
||||
const seconds = (result.durationMs / 1000).toFixed(2);
|
||||
const status = result.code === 0 ? "ok" : "failed";
|
||||
console.log(`${status.padEnd(6)} ${result.name.padEnd(9)} ${seconds}s`);
|
||||
}
|
||||
|
||||
const failures = results.filter((result) => result.code !== 0);
|
||||
|
||||
for (const failure of failures) {
|
||||
console.error(`\n${failure.name} output:`);
|
||||
if (failure.output) {
|
||||
console.error(failure.output.trimEnd());
|
||||
}
|
||||
if (failure.errorOutput) {
|
||||
console.error(failure.errorOutput.trimEnd());
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
process.exit(1);
|
||||
}
|
||||
Loading…
Reference in New Issue