mirror of
https://github.com/kunkunsh/kunkun.git
synced 2025-08-04 18:48:12 +00:00
Feature: add drizzle (#264)
Some checks failed
CI / build-test (macos-14) (push) Has been cancelled
CI / build-test (ubuntu-24.04) (push) Has been cancelled
CI / build-test (windows-latest) (push) Has been cancelled
JSR Publish / publish (push) Has been cancelled
NPM Package Publish / publish-npm (push) Has been cancelled
Some checks failed
CI / build-test (macos-14) (push) Has been cancelled
CI / build-test (ubuntu-24.04) (push) Has been cancelled
CI / build-test (windows-latest) (push) Has been cancelled
JSR Publish / publish (push) Has been cancelled
NPM Package Publish / publish-npm (push) Has been cancelled
* feat: add drizzle orm * feat: update drizzle configuration and schema management - Added a check for DB_FILE_NAME in drizzle.config.ts to ensure it's set. - Updated package.json to change the package name to @kksh/drizzle and added exports for schema and relations. - Enhanced README.md with instructions for using the schema generation. - Refactored schema.ts for improved readability and organization of imports. * add tauri-plugin-sql * feat: add database select and execute commands - Introduced `select` and `execute` functions in the database module to facilitate querying and executing SQL commands. - Updated the Tauri plugin to expose these commands, allowing for database interactions from the frontend. - Added corresponding permissions for the new commands in the permissions configuration. - Enhanced the database library with JSON value handling for query parameters. * fix: sqlite select command * drizzle ORM verified working * refactor: clean up database module by removing unused SelectQueryResult type and disabling eslint for explicit any usage * pnpm lock update * Update enum definition for type safety - Changed enum to use 'as const' for better type inference - Ensured more robust handling of extension publish sources * reimplemented most db command functions with ORM (migrate from tauri command invoke * fixed searchExtensionData orm function * Refactor ORM commands and searchExtensionData function for improved readability and consistency - Reformatted import statements for better organization. - Cleaned up whitespace and indentation in searchExtensionData function. - Enhanced readability of SQL conditions and query building logic. - Disabled eslint for explicit any usage in the troubleshooters page. * Fix test assertions in database module to use array indexing for results format rust code * update deno lock * move drizzle from desktop to drizzle package * update pnpm version and lock * refactor: migrate db tauri commands to drizzle * refactor: remove unused extension and command CRUD operations from db module
This commit is contained in:
parent
bf51fdadbc
commit
bb9a46935c
66 changed files with 3966 additions and 910 deletions
|
@ -17,6 +17,7 @@
|
|||
"dependencies": {
|
||||
"@formkit/auto-animate": "^0.8.2",
|
||||
"@inlang/paraglide-sveltekit": "0.16.0",
|
||||
"@kksh/drizzle": "workspace:*",
|
||||
"@kksh/extension": "workspace:*",
|
||||
"@kksh/svelte5": "^0.1.15",
|
||||
"@kksh/ui": "workspace:*",
|
||||
|
@ -27,9 +28,11 @@
|
|||
"@tauri-apps/api": "^2.3.0",
|
||||
"@tauri-apps/plugin-autostart": "^2.2.0",
|
||||
"@tauri-apps/plugin-shell": "^2.2.0",
|
||||
"@tauri-apps/plugin-sql": "^2.2.0",
|
||||
"@tauri-apps/plugin-stronghold": "^2.2.0",
|
||||
"@tauri-store/svelte": "^2.1.1",
|
||||
"dompurify": "^3.2.4",
|
||||
"drizzle-orm": "^0.40.1",
|
||||
"eslint": "^9.21.0",
|
||||
"fuse.js": "^7.1.0",
|
||||
"gsap": "^3.12.7",
|
||||
|
@ -37,7 +40,7 @@
|
|||
"lz-string": "^1.5.0",
|
||||
"pretty-bytes": "^6.1.1",
|
||||
"semver": "^7.7.1",
|
||||
"svelte-inspect-value": "^0.3.0",
|
||||
"svelte-inspect-value": "^0.5.0",
|
||||
"svelte-sonner": "^0.3.28",
|
||||
"sveltekit-superforms": "^2.23.1",
|
||||
"tauri-plugin-clipboard-api": "^2.1.11",
|
||||
|
|
|
@ -58,6 +58,7 @@ uuid = "1.14.0"
|
|||
obfstr = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
tauri-plugin-stronghold = "2.2.0"
|
||||
tauri-plugin-sql = "2"
|
||||
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
|
|
|
@ -108,6 +108,11 @@ pub fn run() {
|
|||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_cli::init())
|
||||
.plugin(
|
||||
tauri_plugin_sql::Builder::default()
|
||||
// .add_migrations("sqlite:mydatabase.db", migrations)
|
||||
.build(),
|
||||
)
|
||||
.plugin(tauri_plugin_user_input::init())
|
||||
.plugin(tauri_plugin_deep_link::init())
|
||||
.plugin(tauri_plugin_shell::init())
|
||||
|
|
|
@ -242,6 +242,23 @@ export const rawBuiltinCmds: BuiltinCmd[] = [
|
|||
},
|
||||
keywords: ["extension", "troubleshooter"]
|
||||
},
|
||||
{
|
||||
name: "ORM Troubleshooter",
|
||||
icon: {
|
||||
type: IconEnum.Iconify,
|
||||
value: "material-symbols:database"
|
||||
},
|
||||
description: "",
|
||||
flags: {
|
||||
developer: true,
|
||||
dev: true
|
||||
},
|
||||
function: async () => {
|
||||
appState.clearSearchTerm()
|
||||
goto(i18n.resolveRoute("/app/troubleshooters/orm"))
|
||||
},
|
||||
keywords: ["extension", "troubleshooter", "database", "orm"]
|
||||
},
|
||||
{
|
||||
name: "Create Quicklink",
|
||||
icon: {
|
||||
|
|
|
@ -7,10 +7,11 @@ import { decideKkrpcSerialization } from "@/utils/kkrpc"
|
|||
import { sleep } from "@/utils/time"
|
||||
import { trimSlash } from "@/utils/url"
|
||||
import { constructExtensionSupportDir } from "@kksh/api"
|
||||
import { db, spawnExtensionFileServer } from "@kksh/api/commands"
|
||||
import { spawnExtensionFileServer } from "@kksh/api/commands"
|
||||
import type { HeadlessCommand } from "@kksh/api/headless"
|
||||
import { CustomUiCmd, ExtPackageJsonExtra, HeadlessCmd, TemplateUiCmd } from "@kksh/api/models"
|
||||
import { constructJarvisServerAPIWithPermissions, type IApp } from "@kksh/api/ui"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { launchNewExtWindow, loadExtensionManifestFromDisk } from "@kksh/extension"
|
||||
import type { IKunkunFullServerAPI } from "@kunkunapi/src/api/server"
|
||||
import { convertFileSrc } from "@tauri-apps/api/core"
|
||||
|
|
0
apps/desktop/src/lib/orm/cmds.ts
Normal file
0
apps/desktop/src/lib/orm/cmds.ts
Normal file
60
apps/desktop/src/lib/orm/database.ts
Normal file
60
apps/desktop/src/lib/orm/database.ts
Normal file
|
@ -0,0 +1,60 @@
|
|||
// /* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
// import { db as dbCmd } from "@kksh/api/commands"
|
||||
// import * as schema from "@kksh/drizzle/schema"
|
||||
// import { error } from "@tauri-apps/plugin-log"
|
||||
// import { drizzle } from "drizzle-orm/sqlite-proxy"
|
||||
|
||||
// /**
|
||||
// * Loads the sqlite database via the Tauri Proxy.
|
||||
// */
|
||||
// // export const sqlite = await Database.load("sqlite:test.db");
|
||||
|
||||
// /**
|
||||
// * The drizzle database instance.
|
||||
// */
|
||||
// export const db = drizzle<typeof schema>(
|
||||
// async (sql, params, method) => {
|
||||
// let rows: any = []
|
||||
// let results = []
|
||||
// console.log({
|
||||
// sql,
|
||||
// params,
|
||||
// method
|
||||
// })
|
||||
// console.log(sql)
|
||||
// // If the query is a SELECT, use the select method
|
||||
// if (isSelectQuery(sql)) {
|
||||
// rows = await dbCmd.select(sql, params).catch((e) => {
|
||||
// error("SQL Error:", e)
|
||||
// return []
|
||||
// })
|
||||
// } else {
|
||||
// // Otherwise, use the execute method
|
||||
// rows = await dbCmd.execute(sql, params).catch((e) => {
|
||||
// error("SQL Error:", e)
|
||||
// return []
|
||||
// })
|
||||
// return { rows: [] }
|
||||
// }
|
||||
|
||||
// rows = rows.map((row: any) => {
|
||||
// return Object.values(row)
|
||||
// })
|
||||
|
||||
// // If the method is "all", return all rows
|
||||
// results = method === "all" ? rows : rows[0]
|
||||
// return { rows: results }
|
||||
// },
|
||||
// // Pass the schema to the drizzle instance
|
||||
// { schema: schema, logger: true }
|
||||
// )
|
||||
|
||||
// /**
|
||||
// * Checks if the given SQL query is a SELECT query.
|
||||
// * @param sql The SQL query to check.
|
||||
// * @returns True if the query is a SELECT query, false otherwise.
|
||||
// */
|
||||
// function isSelectQuery(sql: string): boolean {
|
||||
// const selectRegex = /^\s*SELECT\b/i
|
||||
// return selectRegex.test(sql)
|
||||
// }
|
|
@ -1,5 +1,5 @@
|
|||
import { db } from "@kksh/api/commands"
|
||||
import type { CustomUiCmd, ExtPackageJsonExtra, HeadlessCmd, TemplateUiCmd } from "@kksh/api/models"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import * as extAPI from "@kksh/extension"
|
||||
import * as path from "@tauri-apps/api/path"
|
||||
import Fuse from "fuse.js"
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
<svelte:window on:keydown={handleKeyDown} />
|
||||
|
||||
<div class="fixed h-12 w-full" data-tauri-drag-region></div>
|
||||
<Layouts.Center class="min-h-screen py-5">
|
||||
<Error.RawErrorJSONPreset
|
||||
title="Error"
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
SystemCmds
|
||||
} from "@kksh/ui/main"
|
||||
import { cn } from "@kksh/ui/utils"
|
||||
import { Ext } from "@kunkunapi/src/models/extension"
|
||||
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow"
|
||||
import { getCurrentWindow, Window } from "@tauri-apps/api/window"
|
||||
import { platform } from "@tauri-apps/plugin-os"
|
||||
|
@ -45,6 +46,7 @@
|
|||
} from "lucide-svelte"
|
||||
import { onMount } from "svelte"
|
||||
import { Inspect } from "svelte-inspect-value"
|
||||
import * as v from "valibot"
|
||||
|
||||
const win = getCurrentWindow()
|
||||
let inputEle: HTMLInputElement | null = $state(null)
|
||||
|
@ -114,6 +116,7 @@
|
|||
<Inspect name="devStoreExtCmds" value={$devStoreExtCmds} />
|
||||
<Inspect name="$appState.searchTerm" value={$appState.searchTerm} />
|
||||
-->
|
||||
|
||||
<Command.Root
|
||||
class={cn("h-screen rounded-lg shadow-md")}
|
||||
bind:value={$appState.highlightedCmd}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
import { goHome } from "@/utils/route"
|
||||
import { listenToNewClipboardItem, listenToWindowFocus } from "@/utils/tauri-events"
|
||||
import Icon from "@iconify/svelte"
|
||||
import { ClipboardContentType, db } from "@kksh/api/commands"
|
||||
import { ClipboardContentType } from "@kksh/api/commands"
|
||||
import { SearchModeEnum, SQLSortOrderEnum, type ExtData } from "@kksh/api/models"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { Button, Command, Resizable } from "@kksh/svelte5"
|
||||
import { Constants } from "@kksh/ui"
|
||||
import { CustomCommandInput, GlobalCommandPaletteFooter } from "@kksh/ui/main"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script lang="ts">
|
||||
import { cn } from "@/utils"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import type { ExtData } from "@kksh/api/models"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { Resizable, Separator } from "@kksh/svelte5"
|
||||
import { convertFileSrc } from "@tauri-apps/api/core"
|
||||
import DOMPurify from "dompurify"
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
import { positionToCssStyleString, positionToTailwindClasses } from "@/utils/style"
|
||||
import { sleep } from "@/utils/time"
|
||||
import { isInMainWindow } from "@/utils/window"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import { CustomPosition, ThemeColor, type Position } from "@kksh/api/models"
|
||||
import {
|
||||
constructJarvisServerAPIWithPermissions,
|
||||
|
@ -19,6 +18,7 @@
|
|||
type IUiCustom
|
||||
} from "@kksh/api/ui"
|
||||
import { toast, type IUiCustomServer1, type IUiCustomServer2 } from "@kksh/api/ui/custom"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { Button } from "@kksh/svelte5"
|
||||
import { cn } from "@kksh/ui/utils"
|
||||
import type { IKunkunFullServerAPI } from "@kunkunapi/src/api/server"
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
import { KunkunIframeExtParams } from "@/cmds/ext"
|
||||
import { i18n } from "@/i18n"
|
||||
import { appState } from "@/stores/appState"
|
||||
import { db, unregisterExtensionWindow } from "@kksh/api/commands"
|
||||
import type { Ext as ExtInfoInDB, ExtPackageJsonExtra } from "@kksh/api/models"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { loadExtensionManifestFromDisk } from "@kksh/extension"
|
||||
import { error as svError } from "@sveltejs/kit"
|
||||
import { join } from "@tauri-apps/api/path"
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
} from "@/utils/tauri-events.js"
|
||||
import { sleep } from "@/utils/time.js"
|
||||
import { isInMainWindow } from "@/utils/window.js"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import {
|
||||
constructJarvisServerAPIWithPermissions,
|
||||
type IApp,
|
||||
|
@ -29,6 +28,7 @@
|
|||
type IComponent,
|
||||
type TemplateUiCommand
|
||||
} from "@kksh/api/ui/template"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { Button, Form } from "@kksh/svelte5"
|
||||
import { LoadingBar } from "@kksh/ui"
|
||||
import { Templates } from "@kksh/ui/extension"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { KunkunTemplateExtParams } from "@/cmds/ext"
|
||||
import { i18n } from "@/i18n"
|
||||
import { db, unregisterExtensionWindow } from "@kksh/api/commands"
|
||||
import type { Ext as ExtInfoInDB, ExtPackageJsonExtra } from "@kksh/api/models"
|
||||
import type { ExtPackageJsonExtra } from "@kksh/api/models"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { loadExtensionManifestFromDisk } from "@kksh/extension"
|
||||
import { error as sbError, error as svError } from "@sveltejs/kit"
|
||||
import { join } from "@tauri-apps/api/path"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<script lang="ts">
|
||||
import * as m from "@/paraglide/messages"
|
||||
import { db } from "@kksh/api/commands"
|
||||
import { db } from "@kksh/drizzle"
|
||||
import { loadExtensionManifestFromDisk } from "@kksh/extension"
|
||||
import { Button, Dialog, Table } from "@kksh/svelte5"
|
||||
import { join } from "@tauri-apps/api/path"
|
||||
|
|
124
apps/desktop/src/routes/app/troubleshooters/orm/+page.svelte
Normal file
124
apps/desktop/src/routes/app/troubleshooters/orm/+page.svelte
Normal file
|
@ -0,0 +1,124 @@
|
|||
<script lang="ts">
|
||||
import {
|
||||
getAllCmds,
|
||||
getAllExtensions,
|
||||
getExtensionDataById,
|
||||
getUniqueExtensionByIdentifier,
|
||||
getUniqueExtensionByPath,
|
||||
searchExtensionData,
|
||||
updateCmdByID
|
||||
} from "@kksh/drizzle/api"
|
||||
import * as schema from "@kksh/drizzle/schema"
|
||||
import { Button, Input } from "@kksh/svelte5"
|
||||
import { CmdTypeEnum, Ext } from "@kunkunapi/src/models/extension"
|
||||
import { SearchModeEnum, SQLSortOrderEnum } from "@kunkunapi/src/models/sql"
|
||||
// import * as orm from "drizzle-orm"
|
||||
import { Inspect } from "svelte-inspect-value"
|
||||
import { toast } from "svelte-sonner"
|
||||
import * as v from "valibot"
|
||||
|
||||
let searchText = $state("")
|
||||
/* eslint-disable */
|
||||
let data: any = $state(null)
|
||||
let inspectTitle = $state("")
|
||||
</script>
|
||||
|
||||
<main class="container space-y-2">
|
||||
<Button
|
||||
onclick={async () => {
|
||||
getAllCmds()
|
||||
.then((cmds) => {
|
||||
console.log(cmds)
|
||||
data = cmds
|
||||
inspectTitle = "All Commands"
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
toast.error("Failed to get all commands", {
|
||||
description: "See console for more details"
|
||||
})
|
||||
})
|
||||
}}
|
||||
>
|
||||
Get All Commands
|
||||
</Button>
|
||||
<Button
|
||||
onclick={() => {
|
||||
getAllExtensions()
|
||||
.then((exts) => {
|
||||
data = exts
|
||||
inspectTitle = "All Extensions"
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
toast.error("Failed to get all extensions", {
|
||||
description: "See console for more details"
|
||||
})
|
||||
})
|
||||
}}
|
||||
>
|
||||
Get All Extensions
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
onclick={async () => {
|
||||
// get all extensions with path not null
|
||||
const exts = await getAllExtensions()
|
||||
for (const ext of exts) {
|
||||
if (ext.path === null) continue
|
||||
const _ext = await getUniqueExtensionByIdentifier(ext.identifier)
|
||||
console.log(_ext)
|
||||
if (ext.path) {
|
||||
const __ext = await getUniqueExtensionByPath(ext.path)
|
||||
console.log(__ext)
|
||||
}
|
||||
}
|
||||
// data = exts
|
||||
}}
|
||||
>
|
||||
Get Unique Extension By Identifier and Path
|
||||
</Button>
|
||||
<!-- <Button
|
||||
onclick={async () => {
|
||||
updateCmdByID({
|
||||
cmdId: 1,
|
||||
name: "google",
|
||||
cmdType: CmdTypeEnum.QuickLink,
|
||||
data: `{"link":"https://google.com/search?query={argument}","icon":{"type":"remote-url","value":"https://google.com/favicon.ico","invert":false}}`,
|
||||
enabled: true
|
||||
})
|
||||
}}
|
||||
>
|
||||
Update Command By ID
|
||||
</Button> -->
|
||||
<Button
|
||||
onclick={async () => {
|
||||
const _data = await getExtensionDataById(1, ["search_text", "data"])
|
||||
data = _data
|
||||
inspectTitle = "Extension Data"
|
||||
}}
|
||||
>
|
||||
Get Extension Data By ID
|
||||
</Button>
|
||||
<form
|
||||
class="flex gap-1"
|
||||
onsubmit={async (e) => {
|
||||
e.preventDefault()
|
||||
const _data = await searchExtensionData({
|
||||
extId: 1,
|
||||
searchMode: SearchModeEnum.FTS,
|
||||
searchText: searchText,
|
||||
orderByCreatedAt: SQLSortOrderEnum.Desc,
|
||||
limit: 10,
|
||||
fields: ["search_text", "data"]
|
||||
})
|
||||
console.log(_data)
|
||||
data = _data
|
||||
inspectTitle = "Search Results"
|
||||
}}
|
||||
>
|
||||
<Input class="" bind:value={searchText} placeholder="Search Text" />
|
||||
<Button class="" type="submit">Search Extension Data</Button>
|
||||
</form>
|
||||
<Inspect name={inspectTitle} value={data} expandLevel={2} />
|
||||
</main>
|
|
@ -6,6 +6,7 @@
|
|||
import { Constants } from "@kksh/ui"
|
||||
import { ArrowLeftIcon } from "lucide-svelte"
|
||||
import AppWindow from "lucide-svelte/icons/app-window"
|
||||
import DB from "lucide-svelte/icons/database"
|
||||
import Loader from "lucide-svelte/icons/loader"
|
||||
import Network from "lucide-svelte/icons/network"
|
||||
|
||||
|
@ -25,6 +26,11 @@
|
|||
title: m.troubleshooters_sidebar_mdns_debugger_title(),
|
||||
url: i18n.resolveRoute("/app/troubleshooters/mdns-debugger"),
|
||||
icon: Network
|
||||
},
|
||||
{
|
||||
title: "ORM",
|
||||
url: i18n.resolveRoute("/app/troubleshooters/orm"),
|
||||
icon: DB
|
||||
}
|
||||
]
|
||||
let currentItem = $state(items.find((item) => window.location.pathname === item.url))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue