mirror of
https://github.com/kunkunsh/kunkun-ext-browser-bookmark.git
synced 2025-04-02 20:46:42 +00:00
init
This commit is contained in:
commit
8de45322f0
23
.github/workflows/jsr-publish.yml
vendored
Normal file
23
.github/workflows/jsr-publish.yml
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
name: JSR Publish
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
publish:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
id-token: write
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: oven-sh/setup-bun@v2
|
||||
- name: Install dependencies
|
||||
run: bun install
|
||||
- name: Build
|
||||
run: bun run build
|
||||
- name: Publish package
|
||||
run: npx jsr publish
|
177
.gitignore
vendored
Normal file
177
.gitignore
vendored
Normal file
@ -0,0 +1,177 @@
|
||||
# Based on https://raw.githubusercontent.com/github/gitignore/main/Node.gitignore
|
||||
|
||||
# Logs
|
||||
|
||||
logs
|
||||
_.log
|
||||
npm-debug.log_
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
lerna-debug.log*
|
||||
.pnpm-debug.log*
|
||||
|
||||
# Caches
|
||||
|
||||
.cache
|
||||
|
||||
# Diagnostic reports (https://nodejs.org/api/report.html)
|
||||
|
||||
report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
||||
|
||||
# Runtime data
|
||||
|
||||
pids
|
||||
_.pid
|
||||
_.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
|
||||
coverage
|
||||
*.lcov
|
||||
|
||||
# nyc test coverage
|
||||
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
|
||||
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (https://nodejs.org/api/addons.html)
|
||||
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Snowpack dependency directory (https://snowpack.dev/)
|
||||
|
||||
web_modules/
|
||||
|
||||
# TypeScript cache
|
||||
|
||||
*.tsbuildinfo
|
||||
|
||||
# Optional npm cache directory
|
||||
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
|
||||
.eslintcache
|
||||
|
||||
# Optional stylelint cache
|
||||
|
||||
.stylelintcache
|
||||
|
||||
# Microbundle cache
|
||||
|
||||
.rpt2_cache/
|
||||
.rts2_cache_cjs/
|
||||
.rts2_cache_es/
|
||||
.rts2_cache_umd/
|
||||
|
||||
# Optional REPL history
|
||||
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
|
||||
*.tgz
|
||||
|
||||
# Yarn Integrity file
|
||||
|
||||
.yarn-integrity
|
||||
|
||||
# dotenv environment variable files
|
||||
|
||||
.env
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
.env.local
|
||||
|
||||
# parcel-bundler cache (https://parceljs.org/)
|
||||
|
||||
.parcel-cache
|
||||
|
||||
# Next.js build output
|
||||
|
||||
.next
|
||||
out
|
||||
|
||||
# Nuxt.js build / generate output
|
||||
|
||||
.nuxt
|
||||
dist
|
||||
|
||||
# Gatsby files
|
||||
|
||||
# Comment in the public line in if your project uses Gatsby and not Next.js
|
||||
|
||||
# https://nextjs.org/blog/next-9-1#public-directory-support
|
||||
|
||||
# public
|
||||
|
||||
# vuepress build output
|
||||
|
||||
.vuepress/dist
|
||||
|
||||
# vuepress v2.x temp and cache directory
|
||||
|
||||
.temp
|
||||
|
||||
# Docusaurus cache and generated files
|
||||
|
||||
.docusaurus
|
||||
|
||||
# Serverless directories
|
||||
|
||||
.serverless/
|
||||
|
||||
# FuseBox cache
|
||||
|
||||
.fusebox/
|
||||
|
||||
# DynamoDB Local files
|
||||
|
||||
.dynamodb/
|
||||
|
||||
# TernJS port file
|
||||
|
||||
.tern-port
|
||||
|
||||
# Stores VSCode versions used for testing VSCode extensions
|
||||
|
||||
.vscode-test
|
||||
|
||||
# yarn v2
|
||||
|
||||
.yarn/cache
|
||||
.yarn/unplugged
|
||||
.yarn/build-state.yml
|
||||
.yarn/install-state.gz
|
||||
.pnp.*
|
||||
|
||||
# IntelliJ based IDEs
|
||||
.idea
|
||||
|
||||
# Finder (MacOS) folder config
|
||||
.DS_Store
|
||||
extensions_support/
|
||||
|
3
.vscode/settings.json
vendored
Normal file
3
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"deno.enable": false
|
||||
}
|
125
README.md
Normal file
125
README.md
Normal file
@ -0,0 +1,125 @@
|
||||
# Kunkun Template UI Extension
|
||||
|
||||
This is a template for a template UI extension. (UI follows pre-defined template)
|
||||
|
||||
[./src/index.ts](./src/index.ts) is the default entrypoint for the extension. You can import any other files in this file, but the build process will bundle them into a single file.
|
||||
|
||||
## Pros and Cons
|
||||
|
||||
This type of extension is suitable for simple use cases, such as a list or form. All components are pre-defined, so there is not much room for customization. If you want more flexibility on the UI, consider using [Custom UI Extension](https://docs.kunkun.sh/extensions/custom-ui-ext/), which requires some frontend knowledge but gives you full control over the UI.
|
||||
|
||||
Read documentation at https://docs.kunkun.sh/extensions/worker-template/
|
||||
|
||||
Make sure you understand what this type of extension is capable of.
|
||||
|
||||
### Pros
|
||||
|
||||
- Simple to develop, no need for any frontend knowledge.
|
||||
- Small bundle size (~40KB)
|
||||
- [Custom UI Extension](https://docs.kunkun.sh/extensions/custom-ui-ext/) are usually larger than 300KB.
|
||||
|
||||
### Cons
|
||||
|
||||
- Limited UI customization. Not suitable for complex use cases.
|
||||
|
||||
Consider [Custom UI Extension](https://docs.kunkun.sh/extensions/custom-ui-ext/) if you need more complex UI.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
pnpm install
|
||||
```
|
||||
|
||||
Start extension in development mode. Every save will trigger a hot reload in Kunkun.
|
||||
|
||||
```bash
|
||||
pnpm dev
|
||||
```
|
||||
|
||||
- During development, right click in Kunkun to open the developer tools.
|
||||
- Error messages will be shown in the console.
|
||||
- If you got any permission error while calling Kunknu's APIs, make sure you've declared the permission in `package.json`. Then go back to home page and enter the extension again to re-apply the permission.
|
||||
- To develop and preview the extension in Kunkun, you need to run the `Add Dev Extension` command in Kunkun, and register this extension's path.
|
||||
|
||||
Build the extension. Your extension source code can contain many files, but the build process will bundle them into a single file.
|
||||
|
||||
```bash
|
||||
pnpm build
|
||||
# Due to Bun's bug, if you are on windows, and install dependencies with pnpm, you may get error during build.
|
||||
# Try install dependencies with bun or npm instead.
|
||||
```
|
||||
|
||||
## i18n
|
||||
|
||||
[./src/i18n](./src/i18n/) contains optional internationalization support starter code.
|
||||
|
||||
If you want to support i18n, you can use the `t` function to translate the strings in the extension.
|
||||
|
||||
User's language setting is available via `app.language()`.
|
||||
|
||||
```ts
|
||||
import { app } from "@kksh/api/ui/worker"
|
||||
import { setupI18n, t } from "./src/i18n"
|
||||
|
||||
setupI18n("zh")
|
||||
console.log(t("welcome"))
|
||||
|
||||
setupI18n(await app.language())
|
||||
console.log(t("welcome"))
|
||||
```
|
||||
|
||||
## Add More Commands
|
||||
|
||||
If you want to add more template worker extension commands, simply modify the `entrypoints` array in [./build.ts](./build.ts).
|
||||
|
||||
Then in `package.json`, register the new command.
|
||||
|
||||
## Verify Build and Publish
|
||||
|
||||
```bash
|
||||
pnpm build # make sure the build npm script works
|
||||
npx kksh@latest verify # Verify some basic settings
|
||||
npx kksh@latest verify --publish # Verify some basic settings before publishing
|
||||
```
|
||||
|
||||
It is recommended to build the extension with the same environment our CI uses.
|
||||
|
||||
The docker image used by our CI is `huakunshen/kunkun-ext-builder:latest`.
|
||||
|
||||
You can use the following command to build the extension with the same environment our CI uses.
|
||||
This requires you to have docker installed, and the shell you are using has access to it via `docker` command.
|
||||
|
||||
```bash
|
||||
npx kksh@latest build # Build the extension with
|
||||
```
|
||||
|
||||
`pnpm` is used to install dependencies and build the extension.
|
||||
|
||||
The docker image environment also has `node`, `pnpm`, `npm`, `bun`, `deno` installed.
|
||||
If your build failed, try debug with `huakunshen/kunkun-ext-builder:latest` image in interative mode and bind your extension volume to `/workspace`.
|
||||
|
||||
After build successfully, you should find a tarball file ends with `.tgz` in the root of your extension.
|
||||
The tarball is packaged with `npm pack` command. You can uncompress it to see if it contains all the necessary files.
|
||||
|
||||
This tarball is the final product that will be published and installed in Kunkun. You can further verify your extension by installing this tarball directly in Kunkun.
|
||||
|
||||
After verifying the tarball, it's ready to be published.
|
||||
|
||||
Fork [KunkunExtensions](https://github.com/kunkunsh/KunkunExtensions) repo, add your extension to the `extensions` directory, and create a PR.
|
||||
|
||||
Once CI passed and PR merged, you can use your extension in Kunkun.
|
||||
|
||||
## Potential Error
|
||||
|
||||
Our CI uses `pnpm` to install dependencies. If you are on Windows, you may get error during build.
|
||||
|
||||
See issue https://github.com/kunkunsh/kunkun/issues/78
|
||||
|
||||
`bun` had problem building the extension when `pnpm` is used to install dependencies.
|
||||
|
||||
### Options
|
||||
|
||||
1. Install an older version of `bun` (1.1.27 should work)
|
||||
2. Install dependencies with `bun` or `npm` instead of `pnpm`
|
||||
|
||||
Our CI always builds the extension with on Linux and shouldn't have this problem.
|
30
build.ts
Normal file
30
build.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { watch } from "fs"
|
||||
import { join } from "path"
|
||||
import { refreshTemplateWorkerExtension } from "@kksh/api/dev"
|
||||
import { $ } from "bun"
|
||||
|
||||
const entrypoints = ["./src/index.ts"]
|
||||
|
||||
async function build() {
|
||||
try {
|
||||
for (const entrypoint of entrypoints) {
|
||||
await $`bun build --minify --target=browser --outdir=./dist ${entrypoint}`
|
||||
}
|
||||
if (Bun.argv.includes("dev")) {
|
||||
await refreshTemplateWorkerExtension()
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(error)
|
||||
}
|
||||
}
|
||||
|
||||
const srcDir = join(import.meta.dir, "src")
|
||||
|
||||
await build()
|
||||
|
||||
if (Bun.argv.includes("dev")) {
|
||||
console.log(`Watching ${srcDir} for changes...`)
|
||||
watch(srcDir, { recursive: true }, async (event, filename) => {
|
||||
await build()
|
||||
})
|
||||
}
|
9
deno-src/deno.json
Normal file
9
deno-src/deno.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"tasks": {
|
||||
"dev": "deno run --watch main.ts"
|
||||
},
|
||||
"imports": {
|
||||
"@kunkun/api": "jsr:@kunkun/api@^0.0.52",
|
||||
"@std/assert": "jsr:@std/assert@1"
|
||||
}
|
||||
}
|
964
deno-src/deno.lock
generated
Normal file
964
deno-src/deno.lock
generated
Normal file
@ -0,0 +1,964 @@
|
||||
{
|
||||
"version": "4",
|
||||
"specifiers": {
|
||||
"jsr:@db/sqlite@0.11": "0.11.1",
|
||||
"jsr:@db/sqlite@0.12.0": "0.12.0",
|
||||
"jsr:@denosaurs/plug@1": "1.0.6",
|
||||
"jsr:@kunkun/api@^0.0.40": "0.0.40",
|
||||
"jsr:@std/assert@0.217": "0.217.0",
|
||||
"jsr:@std/assert@0.221": "0.221.0",
|
||||
"jsr:@std/assert@1": "1.0.8",
|
||||
"jsr:@std/encoding@0.221": "0.221.0",
|
||||
"jsr:@std/fmt@0.221": "0.221.0",
|
||||
"jsr:@std/fs@0.221": "0.221.0",
|
||||
"jsr:@std/internal@^1.0.5": "1.0.5",
|
||||
"jsr:@std/path@0.217": "0.217.0",
|
||||
"jsr:@std/path@0.221": "0.221.0",
|
||||
"jsr:@valibot/valibot@0.42.1": "0.42.1",
|
||||
"npm:@kksh/api@^0.0.40": "0.0.40",
|
||||
"npm:@tauri-apps/api@^2.1.1": "2.1.1",
|
||||
"npm:@tauri-apps/plugin-fs@^2.0.2": "2.0.2",
|
||||
"npm:@tauri-apps/plugin-os@2": "2.0.0",
|
||||
"npm:kkrpc@^0.0.12": "0.0.12_typescript@5.6.3",
|
||||
"npm:lodash@^4.17.21": "4.17.21",
|
||||
"npm:minimatch@^10.0.1": "10.0.1",
|
||||
"npm:semver@^7.6.3": "7.6.3",
|
||||
"npm:svelte-sonner@~0.3.28": "0.3.28_svelte@5.2.7__acorn@8.14.0",
|
||||
"npm:tauri-api-adapter@~0.3.12": "0.3.13_typescript@5.6.3",
|
||||
"npm:tauri-plugin-shellx-api@^2.0.14": "2.0.14",
|
||||
"npm:valibot@0.40": "0.40.0_typescript@5.6.3"
|
||||
},
|
||||
"jsr": {
|
||||
"@db/sqlite@0.11.1": {
|
||||
"integrity": "546434e7ed762db07e6ade0f963540dd5e06723b802937bf260ff855b21ef9c5",
|
||||
"dependencies": [
|
||||
"jsr:@denosaurs/plug",
|
||||
"jsr:@std/path@0.217"
|
||||
]
|
||||
},
|
||||
"@db/sqlite@0.12.0": {
|
||||
"integrity": "dd1ef7f621ad50fc1e073a1c3609c4470bd51edc0994139c5bf9851de7a6d85f",
|
||||
"dependencies": [
|
||||
"jsr:@denosaurs/plug",
|
||||
"jsr:@std/path@0.217"
|
||||
]
|
||||
},
|
||||
"@denosaurs/plug@1.0.6": {
|
||||
"integrity": "6cf5b9daba7799837b9ffbe89f3450510f588fafef8115ddab1ff0be9cb7c1a7",
|
||||
"dependencies": [
|
||||
"jsr:@std/encoding",
|
||||
"jsr:@std/fmt",
|
||||
"jsr:@std/fs",
|
||||
"jsr:@std/path@0.221"
|
||||
]
|
||||
},
|
||||
"@kunkun/api@0.0.40": {
|
||||
"integrity": "eab67c01e1cc87f3e5e7f7613a302cba7fccb18a1745f1a5508cf48df1e3649e",
|
||||
"dependencies": [
|
||||
"npm:@kksh/api",
|
||||
"npm:@tauri-apps/api",
|
||||
"npm:@tauri-apps/plugin-fs",
|
||||
"npm:@tauri-apps/plugin-os",
|
||||
"npm:kkrpc",
|
||||
"npm:lodash",
|
||||
"npm:minimatch",
|
||||
"npm:semver",
|
||||
"npm:svelte-sonner",
|
||||
"npm:tauri-api-adapter",
|
||||
"npm:tauri-plugin-shellx-api",
|
||||
"npm:valibot"
|
||||
]
|
||||
},
|
||||
"@std/assert@0.217.0": {
|
||||
"integrity": "c98e279362ca6982d5285c3b89517b757c1e3477ee9f14eb2fdf80a45aaa9642"
|
||||
},
|
||||
"@std/assert@0.221.0": {
|
||||
"integrity": "a5f1aa6e7909dbea271754fd4ab3f4e687aeff4873b4cef9a320af813adb489a"
|
||||
},
|
||||
"@std/assert@1.0.8": {
|
||||
"integrity": "ebe0bd7eb488ee39686f77003992f389a06c3da1bbd8022184804852b2fa641b",
|
||||
"dependencies": [
|
||||
"jsr:@std/internal"
|
||||
]
|
||||
},
|
||||
"@std/encoding@0.221.0": {
|
||||
"integrity": "d1dd76ef0dc5d14088411e6dc1dede53bf8308c95d1537df1214c97137208e45"
|
||||
},
|
||||
"@std/fmt@0.221.0": {
|
||||
"integrity": "379fed69bdd9731110f26b9085aeb740606b20428ce6af31ef6bd45ef8efa62a"
|
||||
},
|
||||
"@std/fs@0.221.0": {
|
||||
"integrity": "028044450299de8ed5a716ade4e6d524399f035513b85913794f4e81f07da286",
|
||||
"dependencies": [
|
||||
"jsr:@std/assert@0.221",
|
||||
"jsr:@std/path@0.221"
|
||||
]
|
||||
},
|
||||
"@std/internal@1.0.5": {
|
||||
"integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba"
|
||||
},
|
||||
"@std/path@0.217.0": {
|
||||
"integrity": "1217cc25534bca9a2f672d7fe7c6f356e4027df400c0e85c0ef3e4343bc67d11",
|
||||
"dependencies": [
|
||||
"jsr:@std/assert@0.217"
|
||||
]
|
||||
},
|
||||
"@std/path@0.221.0": {
|
||||
"integrity": "0a36f6b17314ef653a3a1649740cc8db51b25a133ecfe838f20b79a56ebe0095",
|
||||
"dependencies": [
|
||||
"jsr:@std/assert@0.221"
|
||||
]
|
||||
},
|
||||
"@valibot/valibot@0.42.1": {
|
||||
"integrity": "ba0f6f7964aaeec0e4b1f793d575061f325ae6254cbb9d7ff01fb65068a0a23b"
|
||||
}
|
||||
},
|
||||
"npm": {
|
||||
"@ampproject/remapping@2.3.0": {
|
||||
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
|
||||
"dependencies": [
|
||||
"@jridgewell/gen-mapping",
|
||||
"@jridgewell/trace-mapping"
|
||||
]
|
||||
},
|
||||
"@isaacs/cliui@8.0.2": {
|
||||
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
|
||||
"dependencies": [
|
||||
"string-width@5.1.2",
|
||||
"string-width-cjs@npm:string-width@4.2.3",
|
||||
"strip-ansi@7.1.0",
|
||||
"strip-ansi-cjs@npm:strip-ansi@6.0.1",
|
||||
"wrap-ansi@8.1.0",
|
||||
"wrap-ansi-cjs@npm:wrap-ansi@7.0.0"
|
||||
]
|
||||
},
|
||||
"@jridgewell/gen-mapping@0.3.5": {
|
||||
"integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==",
|
||||
"dependencies": [
|
||||
"@jridgewell/set-array",
|
||||
"@jridgewell/sourcemap-codec",
|
||||
"@jridgewell/trace-mapping"
|
||||
]
|
||||
},
|
||||
"@jridgewell/resolve-uri@3.1.2": {
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="
|
||||
},
|
||||
"@jridgewell/set-array@1.2.1": {
|
||||
"integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A=="
|
||||
},
|
||||
"@jridgewell/sourcemap-codec@1.5.0": {
|
||||
"integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ=="
|
||||
},
|
||||
"@jridgewell/trace-mapping@0.3.25": {
|
||||
"integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==",
|
||||
"dependencies": [
|
||||
"@jridgewell/resolve-uri",
|
||||
"@jridgewell/sourcemap-codec"
|
||||
]
|
||||
},
|
||||
"@kksh/api@0.0.40": {
|
||||
"integrity": "sha512-g7n/vwGWs+5OMdxHUPOFKaX7vPqzTfXkRPTR33G+fWv6mdaypaS6fOAMnGmcoEgLPzL4RPO1WaL3+ypSCV620A==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1",
|
||||
"@tauri-apps/cli",
|
||||
"@tauri-apps/plugin-deep-link",
|
||||
"@tauri-apps/plugin-dialog",
|
||||
"@tauri-apps/plugin-fs",
|
||||
"@tauri-apps/plugin-global-shortcut",
|
||||
"@tauri-apps/plugin-http",
|
||||
"@tauri-apps/plugin-log",
|
||||
"@tauri-apps/plugin-notification",
|
||||
"@tauri-apps/plugin-os",
|
||||
"@tauri-apps/plugin-process",
|
||||
"@tauri-apps/plugin-shell",
|
||||
"@tauri-apps/plugin-store",
|
||||
"@tauri-apps/plugin-updater",
|
||||
"@tauri-apps/plugin-upload",
|
||||
"kkrpc@0.0.10_typescript@5.6.3",
|
||||
"lodash",
|
||||
"minimatch@10.0.1",
|
||||
"semver",
|
||||
"svelte-sonner",
|
||||
"tauri-api-adapter",
|
||||
"tauri-plugin-network-api@2.0.4",
|
||||
"tauri-plugin-shellx-api",
|
||||
"tauri-plugin-system-info-api@2.0.8",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"@nodelib/fs.scandir@2.1.5": {
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dependencies": [
|
||||
"@nodelib/fs.stat",
|
||||
"run-parallel"
|
||||
]
|
||||
},
|
||||
"@nodelib/fs.stat@2.0.5": {
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="
|
||||
},
|
||||
"@nodelib/fs.walk@1.2.8": {
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dependencies": [
|
||||
"@nodelib/fs.scandir",
|
||||
"fastq"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/api@2.0.1": {
|
||||
"integrity": "sha512-eoQWT+Tq1qSwQpHV+nw1eNYe5B/nm1PoRjQCRiEOS12I1b+X4PUcREfXVX8dPcBT6GrzWGDtaecY0+1p0Rfqlw=="
|
||||
},
|
||||
"@tauri-apps/api@2.1.1": {
|
||||
"integrity": "sha512-fzUfFFKo4lknXGJq8qrCidkUcKcH2UHhfaaCNt4GzgzGaW2iS26uFOg4tS3H4P8D6ZEeUxtiD5z0nwFF0UN30A=="
|
||||
},
|
||||
"@tauri-apps/cli-darwin-arm64@2.1.0": {
|
||||
"integrity": "sha512-ESc6J6CE8hl1yKH2vJ+ALF+thq4Be+DM1mvmTyUCQObvezNCNhzfS6abIUd3ou4x5RGH51ouiANeT3wekU6dCw=="
|
||||
},
|
||||
"@tauri-apps/cli-darwin-x64@2.1.0": {
|
||||
"integrity": "sha512-TasHS442DFs8cSH2eUQzuDBXUST4ECjCd0yyP+zZzvAruiB0Bg+c8A+I/EnqCvBQ2G2yvWLYG8q/LI7c87A5UA=="
|
||||
},
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf@2.1.0": {
|
||||
"integrity": "sha512-aP7ZBGNL4ny07Cbb6kKpUOSrmhcIK2KhjviTzYlh+pPhAptxnC78xQGD3zKQkTi2WliJLPmBYbOHWWQa57lQ9w=="
|
||||
},
|
||||
"@tauri-apps/cli-linux-arm64-gnu@2.1.0": {
|
||||
"integrity": "sha512-ZTdgD5gLeMCzndMT2f358EkoYkZ5T+Qy6zPzU+l5vv5M7dHVN9ZmblNAYYXmoOuw7y+BY4X/rZvHV9pcGrcanQ=="
|
||||
},
|
||||
"@tauri-apps/cli-linux-arm64-musl@2.1.0": {
|
||||
"integrity": "sha512-NzwqjUCilhnhJzusz3d/0i0F1GFrwCQbkwR6yAHUxItESbsGYkZRJk0yMEWkg3PzFnyK4cWTlQJMEU52TjhEzA=="
|
||||
},
|
||||
"@tauri-apps/cli-linux-x64-gnu@2.1.0": {
|
||||
"integrity": "sha512-TyiIpMEtZxNOQmuFyfJwaaYbg3movSthpBJLIdPlKxSAB2BW0VWLY3/ZfIxm/G2YGHyREkjJvimzYE0i37PnMA=="
|
||||
},
|
||||
"@tauri-apps/cli-linux-x64-musl@2.1.0": {
|
||||
"integrity": "sha512-/dQd0TlaxBdJACrR72DhynWftzHDaX32eBtS5WBrNJ+nnNb+znM3gON6nJ9tSE9jgDa6n1v2BkI/oIDtypfUXw=="
|
||||
},
|
||||
"@tauri-apps/cli-win32-arm64-msvc@2.1.0": {
|
||||
"integrity": "sha512-NdQJO7SmdYqOcE+JPU7bwg7+odfZMWO6g8xF9SXYCMdUzvM2Gv/AQfikNXz5yS7ralRhNFuW32i5dcHlxh4pDg=="
|
||||
},
|
||||
"@tauri-apps/cli-win32-ia32-msvc@2.1.0": {
|
||||
"integrity": "sha512-f5h8gKT/cB8s1ticFRUpNmHqkmaLutT62oFDB7N//2YTXnxst7EpMIn1w+QimxTvTk2gcx6EcW6bEk/y2hZGzg=="
|
||||
},
|
||||
"@tauri-apps/cli-win32-x64-msvc@2.1.0": {
|
||||
"integrity": "sha512-P/+LrdSSb5Xbho1LRP4haBjFHdyPdjWvGgeopL96OVtrFpYnfC+RctB45z2V2XxqFk3HweDDxk266btjttfjGw=="
|
||||
},
|
||||
"@tauri-apps/cli@2.1.0": {
|
||||
"integrity": "sha512-K2VhcKqBhAeS5pNOVdnR/xQRU6jwpgmkSL2ejHXcl0m+kaTggT0WRDQnFtPq6NljA7aE03cvwsbCAoFG7vtkJw==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/cli-darwin-arm64",
|
||||
"@tauri-apps/cli-darwin-x64",
|
||||
"@tauri-apps/cli-linux-arm-gnueabihf",
|
||||
"@tauri-apps/cli-linux-arm64-gnu",
|
||||
"@tauri-apps/cli-linux-arm64-musl",
|
||||
"@tauri-apps/cli-linux-x64-gnu",
|
||||
"@tauri-apps/cli-linux-x64-musl",
|
||||
"@tauri-apps/cli-win32-arm64-msvc",
|
||||
"@tauri-apps/cli-win32-ia32-msvc",
|
||||
"@tauri-apps/cli-win32-x64-msvc"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-deep-link@2.0.0": {
|
||||
"integrity": "sha512-cDa2k1OrRU5DoKc0IXl1Y8RlFOU107u2phdZfT7FkApsC6TL/VAPs3YOUTT8p9/PZ50EjOKP104HFMqVqnQ0bw==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-dialog@2.0.1": {
|
||||
"integrity": "sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-fs@2.0.2": {
|
||||
"integrity": "sha512-4YZaX2j7ta81M5/DL8aN10kTnpUkEpkPo1FTYPT8Dd0ImHe3azM8i8MrtjrDGoyBYLPO3zFv7df/mSCYF8oA0Q==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-global-shortcut@2.0.0": {
|
||||
"integrity": "sha512-pnB4CUwFVjg4twtBSxoLJ4uLFTYxsvOdC1zIbG581pYzhYatOl6mjB+ijD5SSXgiS/jNoqMcfkOF9PWAisurew==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-http@2.0.1": {
|
||||
"integrity": "sha512-j6IA3pVBybSCwPpsihpX4z8bs6PluuGtr06ahL/xy4D8HunNBTmRmadJrFOQi0gOAbaig4MkQ15nzNLBLy8R1A==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-log@2.0.0": {
|
||||
"integrity": "sha512-C+NII9vzswqnOQE8k7oRtnaw0z5TZsMmnirRhXkCKDEhQQH9841Us/PC1WHtGiAaJ8za1A1JB2xXndEq/47X/w==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-notification@2.0.0": {
|
||||
"integrity": "sha512-6qEDYJS7mgXZWLXA0EFL+DVCJh8sJlzSoyw6B50pxhLPVFjc5Vr5DVzl5W3mUHaYhod5wsC984eQnlCCGqxYDA==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-os@2.0.0": {
|
||||
"integrity": "sha512-M7hG/nNyQYTJxVG/UhTKhp9mpXriwWzrs9mqDreB8mIgqA3ek5nHLdwRZJWhkKjZrnDT4v9CpA9BhYeplTlAiA==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-process@2.0.0": {
|
||||
"integrity": "sha512-OYzi0GnkrF4NAnsHZU7U3tjSoP0PbeAlO7T1Z+vJoBUH9sFQ1NSLqWYWQyf8hcb3gVWe7P1JggjiskO+LST1ug==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-shell@2.0.1": {
|
||||
"integrity": "sha512-akU1b77sw3qHiynrK0s930y8zKmcdrSD60htjH+mFZqv5WaakZA/XxHR3/sF1nNv9Mgmt/Shls37HwnOr00aSw==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-store@2.1.0": {
|
||||
"integrity": "sha512-GADqrc17opUKYIAKnGHIUgEeTZ2wJGu1ZITKQ1WMuOFdv8fvXRFBAqsqPjE3opgWohbczX6e1NpwmZK1AnuWVw==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-updater@2.0.0": {
|
||||
"integrity": "sha512-N0cl71g7RPr7zK2Fe5aoIwzw14NcdLcz7XMGFWZVjprsqgDRWoxbnUkknyCQMZthjhGkppCd/wN2MIsUz+eAhQ==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@tauri-apps/plugin-upload@2.1.0": {
|
||||
"integrity": "sha512-nSIyxp2sAHsj+1RMs3obTP2lC1rzeWcMxHtzLYjnXLnJMXvWlFG0T7jEZ9Sg/OErvQxPVIvDW+12evuFKa5t8Q==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"@types/estree@1.0.6": {
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="
|
||||
},
|
||||
"acorn-typescript@1.4.13_acorn@8.14.0": {
|
||||
"integrity": "sha512-xsc9Xv0xlVfwp2o7sQ+GCQ1PgbkdcpWdTzrwXxO3xDMTAywVS3oXVOcOHuRjAPkS4P9b+yc/qNF15460v+jp4Q==",
|
||||
"dependencies": [
|
||||
"acorn"
|
||||
]
|
||||
},
|
||||
"acorn@8.14.0": {
|
||||
"integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="
|
||||
},
|
||||
"ansi-regex@5.0.1": {
|
||||
"integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="
|
||||
},
|
||||
"ansi-regex@6.1.0": {
|
||||
"integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA=="
|
||||
},
|
||||
"ansi-styles@4.3.0": {
|
||||
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
|
||||
"dependencies": [
|
||||
"color-convert"
|
||||
]
|
||||
},
|
||||
"ansi-styles@6.2.1": {
|
||||
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug=="
|
||||
},
|
||||
"anymatch@3.1.3": {
|
||||
"integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
|
||||
"dependencies": [
|
||||
"normalize-path",
|
||||
"picomatch"
|
||||
]
|
||||
},
|
||||
"aria-query@5.3.2": {
|
||||
"integrity": "sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw=="
|
||||
},
|
||||
"array-union@2.1.0": {
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="
|
||||
},
|
||||
"axobject-query@4.1.0": {
|
||||
"integrity": "sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ=="
|
||||
},
|
||||
"balanced-match@1.0.2": {
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"binary-extensions@2.3.0": {
|
||||
"integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="
|
||||
},
|
||||
"brace-expansion@1.1.11": {
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dependencies": [
|
||||
"balanced-match",
|
||||
"concat-map"
|
||||
]
|
||||
},
|
||||
"brace-expansion@2.0.1": {
|
||||
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
|
||||
"dependencies": [
|
||||
"balanced-match"
|
||||
]
|
||||
},
|
||||
"braces@3.0.3": {
|
||||
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
|
||||
"dependencies": [
|
||||
"fill-range"
|
||||
]
|
||||
},
|
||||
"chokidar@3.6.0": {
|
||||
"integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
|
||||
"dependencies": [
|
||||
"anymatch",
|
||||
"braces",
|
||||
"fsevents",
|
||||
"glob-parent",
|
||||
"is-binary-path",
|
||||
"is-glob",
|
||||
"normalize-path",
|
||||
"readdirp"
|
||||
]
|
||||
},
|
||||
"color-convert@2.0.1": {
|
||||
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
|
||||
"dependencies": [
|
||||
"color-name"
|
||||
]
|
||||
},
|
||||
"color-name@1.1.4": {
|
||||
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
|
||||
},
|
||||
"commander@9.5.0": {
|
||||
"integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="
|
||||
},
|
||||
"concat-map@0.0.1": {
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"cross-spawn@7.0.6": {
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dependencies": [
|
||||
"path-key",
|
||||
"shebang-command",
|
||||
"which"
|
||||
]
|
||||
},
|
||||
"dir-glob@3.0.1": {
|
||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||
"dependencies": [
|
||||
"path-type"
|
||||
]
|
||||
},
|
||||
"eastasianwidth@0.2.0": {
|
||||
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA=="
|
||||
},
|
||||
"emoji-regex@8.0.0": {
|
||||
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
|
||||
},
|
||||
"emoji-regex@9.2.2": {
|
||||
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg=="
|
||||
},
|
||||
"esm-env@1.1.4": {
|
||||
"integrity": "sha512-oO82nKPHKkzIj/hbtuDYy/JHqBHFlMIW36SDiPCVsj87ntDLcWN+sJ1erdVryd4NxODacFTsdrIE3b7IamqbOg=="
|
||||
},
|
||||
"esrap@1.2.2": {
|
||||
"integrity": "sha512-F2pSJklxx1BlQIQgooczXCPHmcWpn6EsP5oo73LQfonG9fIlIENQ8vMmfGXeojP9MrkzUNAfyU5vdFlR9shHAw==",
|
||||
"dependencies": [
|
||||
"@jridgewell/sourcemap-codec",
|
||||
"@types/estree"
|
||||
]
|
||||
},
|
||||
"fast-glob@3.3.2": {
|
||||
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
|
||||
"dependencies": [
|
||||
"@nodelib/fs.stat",
|
||||
"@nodelib/fs.walk",
|
||||
"glob-parent",
|
||||
"merge2",
|
||||
"micromatch"
|
||||
]
|
||||
},
|
||||
"fastq@1.17.1": {
|
||||
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
|
||||
"dependencies": [
|
||||
"reusify"
|
||||
]
|
||||
},
|
||||
"fill-range@7.1.1": {
|
||||
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
|
||||
"dependencies": [
|
||||
"to-regex-range"
|
||||
]
|
||||
},
|
||||
"foreground-child@3.3.0": {
|
||||
"integrity": "sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==",
|
||||
"dependencies": [
|
||||
"cross-spawn",
|
||||
"signal-exit"
|
||||
]
|
||||
},
|
||||
"fs.realpath@1.0.0": {
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"fsevents@2.3.3": {
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="
|
||||
},
|
||||
"function-bind@1.1.2": {
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="
|
||||
},
|
||||
"glob-parent@5.1.2": {
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dependencies": [
|
||||
"is-glob"
|
||||
]
|
||||
},
|
||||
"glob@11.0.0": {
|
||||
"integrity": "sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g==",
|
||||
"dependencies": [
|
||||
"foreground-child",
|
||||
"jackspeak",
|
||||
"minimatch@10.0.1",
|
||||
"minipass",
|
||||
"package-json-from-dist",
|
||||
"path-scurry"
|
||||
]
|
||||
},
|
||||
"glob@7.2.3": {
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"dependencies": [
|
||||
"fs.realpath",
|
||||
"inflight",
|
||||
"inherits",
|
||||
"minimatch@3.1.2",
|
||||
"once",
|
||||
"path-is-absolute"
|
||||
]
|
||||
},
|
||||
"globby@11.1.0": {
|
||||
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
||||
"dependencies": [
|
||||
"array-union",
|
||||
"dir-glob",
|
||||
"fast-glob",
|
||||
"ignore",
|
||||
"merge2",
|
||||
"slash"
|
||||
]
|
||||
},
|
||||
"hasown@2.0.2": {
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dependencies": [
|
||||
"function-bind"
|
||||
]
|
||||
},
|
||||
"ignore@5.3.2": {
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="
|
||||
},
|
||||
"inflight@1.0.6": {
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"dependencies": [
|
||||
"once",
|
||||
"wrappy"
|
||||
]
|
||||
},
|
||||
"inherits@2.0.4": {
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"interpret@1.4.0": {
|
||||
"integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
|
||||
},
|
||||
"is-binary-path@2.1.0": {
|
||||
"integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
|
||||
"dependencies": [
|
||||
"binary-extensions"
|
||||
]
|
||||
},
|
||||
"is-core-module@2.15.1": {
|
||||
"integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==",
|
||||
"dependencies": [
|
||||
"hasown"
|
||||
]
|
||||
},
|
||||
"is-extglob@2.1.1": {
|
||||
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
|
||||
},
|
||||
"is-fullwidth-code-point@3.0.0": {
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="
|
||||
},
|
||||
"is-glob@4.0.3": {
|
||||
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
|
||||
"dependencies": [
|
||||
"is-extglob"
|
||||
]
|
||||
},
|
||||
"is-number@7.0.0": {
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"is-reference@3.0.3": {
|
||||
"integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==",
|
||||
"dependencies": [
|
||||
"@types/estree"
|
||||
]
|
||||
},
|
||||
"isexe@2.0.0": {
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"jackspeak@4.0.2": {
|
||||
"integrity": "sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw==",
|
||||
"dependencies": [
|
||||
"@isaacs/cliui"
|
||||
]
|
||||
},
|
||||
"kkrpc@0.0.10_typescript@5.6.3": {
|
||||
"integrity": "sha512-lkQKVnN9f6JrS4ybKbGkV4mtuGhWYLTnaWx60ysytEap+sP5jcTbAuJlSrY6JqlwaohiS0X3ZbvJ2rAXYRdTng==",
|
||||
"dependencies": [
|
||||
"typescript",
|
||||
"ws"
|
||||
]
|
||||
},
|
||||
"kkrpc@0.0.12_typescript@5.6.3": {
|
||||
"integrity": "sha512-PBk4AhGfkesIdAwmIoj7dHHIp7qN97XT4yr5Rl7h2WL79gxWQVgZRJYLt7Gb17GoLDh991rnL85mhCoPG5VC/Q==",
|
||||
"dependencies": [
|
||||
"typescript",
|
||||
"ws"
|
||||
]
|
||||
},
|
||||
"locate-character@3.0.0": {
|
||||
"integrity": "sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA=="
|
||||
},
|
||||
"lodash@4.17.21": {
|
||||
"integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
|
||||
},
|
||||
"lru-cache@11.0.2": {
|
||||
"integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA=="
|
||||
},
|
||||
"magic-string@0.30.13": {
|
||||
"integrity": "sha512-8rYBO+MsWkgjDSOvLomYnzhdwEG51olQ4zL5KXnNJWV5MNmrb4rTZdrtkhxjnD/QyZUqR/Z/XDsUs/4ej2nx0g==",
|
||||
"dependencies": [
|
||||
"@jridgewell/sourcemap-codec"
|
||||
]
|
||||
},
|
||||
"merge2@1.4.1": {
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="
|
||||
},
|
||||
"micromatch@4.0.8": {
|
||||
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
|
||||
"dependencies": [
|
||||
"braces",
|
||||
"picomatch"
|
||||
]
|
||||
},
|
||||
"minimatch@10.0.1": {
|
||||
"integrity": "sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ==",
|
||||
"dependencies": [
|
||||
"brace-expansion@2.0.1"
|
||||
]
|
||||
},
|
||||
"minimatch@3.1.2": {
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dependencies": [
|
||||
"brace-expansion@1.1.11"
|
||||
]
|
||||
},
|
||||
"minimist@1.2.8": {
|
||||
"integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="
|
||||
},
|
||||
"minipass@7.1.2": {
|
||||
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw=="
|
||||
},
|
||||
"mylas@2.1.13": {
|
||||
"integrity": "sha512-+MrqnJRtxdF+xngFfUUkIMQrUUL0KsxbADUkn23Z/4ibGg192Q+z+CQyiYwvWTsYjJygmMR8+w3ZDa98Zh6ESg=="
|
||||
},
|
||||
"normalize-path@3.0.0": {
|
||||
"integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="
|
||||
},
|
||||
"once@1.4.0": {
|
||||
"integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
|
||||
"dependencies": [
|
||||
"wrappy"
|
||||
]
|
||||
},
|
||||
"package-json-from-dist@1.0.1": {
|
||||
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw=="
|
||||
},
|
||||
"path-is-absolute@1.0.1": {
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
|
||||
},
|
||||
"path-key@3.1.1": {
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
|
||||
},
|
||||
"path-parse@1.0.7": {
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"path-scurry@2.0.0": {
|
||||
"integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==",
|
||||
"dependencies": [
|
||||
"lru-cache",
|
||||
"minipass"
|
||||
]
|
||||
},
|
||||
"path-type@4.0.0": {
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw=="
|
||||
},
|
||||
"picomatch@2.3.1": {
|
||||
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
|
||||
},
|
||||
"plimit-lit@1.6.1": {
|
||||
"integrity": "sha512-B7+VDyb8Tl6oMJT9oSO2CW8XC/T4UcJGrwOVoNGwOQsQYhlpfajmrMj5xeejqaASq3V/EqThyOeATEOMuSEXiA==",
|
||||
"dependencies": [
|
||||
"queue-lit"
|
||||
]
|
||||
},
|
||||
"queue-lit@1.5.2": {
|
||||
"integrity": "sha512-tLc36IOPeMAubu8BkW8YDBV+WyIgKlYU7zUNs0J5Vk9skSZ4JfGlPOqplP0aHdfv7HL0B2Pg6nwiq60Qc6M2Hw=="
|
||||
},
|
||||
"queue-microtask@1.2.3": {
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="
|
||||
},
|
||||
"readdirp@3.6.0": {
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dependencies": [
|
||||
"picomatch"
|
||||
]
|
||||
},
|
||||
"rechoir@0.6.2": {
|
||||
"integrity": "sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==",
|
||||
"dependencies": [
|
||||
"resolve"
|
||||
]
|
||||
},
|
||||
"resolve@1.22.8": {
|
||||
"integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==",
|
||||
"dependencies": [
|
||||
"is-core-module",
|
||||
"path-parse",
|
||||
"supports-preserve-symlinks-flag"
|
||||
]
|
||||
},
|
||||
"reusify@1.0.4": {
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw=="
|
||||
},
|
||||
"rimraf@6.0.1": {
|
||||
"integrity": "sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A==",
|
||||
"dependencies": [
|
||||
"glob@11.0.0",
|
||||
"package-json-from-dist"
|
||||
]
|
||||
},
|
||||
"run-parallel@1.2.0": {
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dependencies": [
|
||||
"queue-microtask"
|
||||
]
|
||||
},
|
||||
"semver@7.6.3": {
|
||||
"integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A=="
|
||||
},
|
||||
"shebang-command@2.0.0": {
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dependencies": [
|
||||
"shebang-regex"
|
||||
]
|
||||
},
|
||||
"shebang-regex@3.0.0": {
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
|
||||
},
|
||||
"shelljs@0.8.5": {
|
||||
"integrity": "sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==",
|
||||
"dependencies": [
|
||||
"glob@7.2.3",
|
||||
"interpret",
|
||||
"rechoir"
|
||||
]
|
||||
},
|
||||
"shx@0.3.4": {
|
||||
"integrity": "sha512-N6A9MLVqjxZYcVn8hLmtneQWIJtp8IKzMP4eMnx+nqkvXoqinUPCbUFLp2UcWTEIUONhlk0ewxr/jaVGlc+J+g==",
|
||||
"dependencies": [
|
||||
"minimist",
|
||||
"shelljs"
|
||||
]
|
||||
},
|
||||
"signal-exit@4.1.0": {
|
||||
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="
|
||||
},
|
||||
"slash@3.0.0": {
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
|
||||
},
|
||||
"string-width@4.2.3": {
|
||||
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
|
||||
"dependencies": [
|
||||
"emoji-regex@8.0.0",
|
||||
"is-fullwidth-code-point",
|
||||
"strip-ansi@6.0.1"
|
||||
]
|
||||
},
|
||||
"string-width@5.1.2": {
|
||||
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
|
||||
"dependencies": [
|
||||
"eastasianwidth",
|
||||
"emoji-regex@9.2.2",
|
||||
"strip-ansi@7.1.0"
|
||||
]
|
||||
},
|
||||
"strip-ansi@6.0.1": {
|
||||
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
|
||||
"dependencies": [
|
||||
"ansi-regex@5.0.1"
|
||||
]
|
||||
},
|
||||
"strip-ansi@7.1.0": {
|
||||
"integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
|
||||
"dependencies": [
|
||||
"ansi-regex@6.1.0"
|
||||
]
|
||||
},
|
||||
"supports-preserve-symlinks-flag@1.0.0": {
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"svelte-sonner@0.3.28_svelte@5.2.7__acorn@8.14.0": {
|
||||
"integrity": "sha512-K3AmlySeFifF/cKgsYNv5uXqMVNln0NBAacOYgmkQStLa/UoU0LhfAACU6Gr+YYC8bOCHdVmFNoKuDbMEsppJg==",
|
||||
"dependencies": [
|
||||
"svelte"
|
||||
]
|
||||
},
|
||||
"svelte@5.2.7_acorn@8.14.0": {
|
||||
"integrity": "sha512-cEhPGuLHiH2+Z8B1FwQgiZJgA39uUmJR4516TKrM5zrp0/cuwJkfhUfcTxhAkznanAF5fXUKzvYR4o+Ksx3ZCQ==",
|
||||
"dependencies": [
|
||||
"@ampproject/remapping",
|
||||
"@jridgewell/sourcemap-codec",
|
||||
"@types/estree",
|
||||
"acorn",
|
||||
"acorn-typescript",
|
||||
"aria-query",
|
||||
"axobject-query",
|
||||
"esm-env",
|
||||
"esrap",
|
||||
"is-reference",
|
||||
"locate-character",
|
||||
"magic-string",
|
||||
"zimmerframe"
|
||||
]
|
||||
},
|
||||
"tauri-api-adapter@0.3.13_typescript@5.6.3": {
|
||||
"integrity": "sha512-ex4z3Zish6by1ew1ialbLc5g3dhly+6ihepJeJwVRQoMJdUTyfCX2dVPYW74i+px1hFXKFu3MYTheS7uBOeCbg==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1",
|
||||
"@tauri-apps/plugin-dialog",
|
||||
"@tauri-apps/plugin-fs",
|
||||
"@tauri-apps/plugin-http",
|
||||
"@tauri-apps/plugin-log",
|
||||
"@tauri-apps/plugin-notification",
|
||||
"@tauri-apps/plugin-os",
|
||||
"@tauri-apps/plugin-shell",
|
||||
"@tauri-apps/plugin-upload",
|
||||
"kkrpc@0.0.12_typescript@5.6.3",
|
||||
"rimraf",
|
||||
"shx",
|
||||
"tauri-plugin-clipboard-api",
|
||||
"tauri-plugin-network-api@2.0.4_typescript@5.6.3",
|
||||
"tauri-plugin-shellx-api",
|
||||
"tauri-plugin-system-info-api@2.0.8_typescript@5.6.3",
|
||||
"tsc-alias",
|
||||
"typescript",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"tauri-plugin-clipboard-api@2.1.11_typescript@5.6.3": {
|
||||
"integrity": "sha512-VNkGaVPPfRoHg7/rJBcWqsvLvn4/kNEOOlzqwyI9Qdf6g54B3mc31GLZdnq/HWtX0vZskw3J8b/EF9YkASDCBQ==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.0.1",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"tauri-plugin-network-api@2.0.4": {
|
||||
"integrity": "sha512-CJWF2g+uQifcIlE/AXUnezVjjbyY0FDBxoz4P6BmjNRR/qubpNMfdUnKLqdjX98o5MIXGW+UnyZTfbJo998dFw==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"tauri-plugin-network-api@2.0.4_typescript@5.6.3": {
|
||||
"integrity": "sha512-CJWF2g+uQifcIlE/AXUnezVjjbyY0FDBxoz4P6BmjNRR/qubpNMfdUnKLqdjX98o5MIXGW+UnyZTfbJo998dFw==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"tauri-plugin-shellx-api@2.0.14": {
|
||||
"integrity": "sha512-MdSYD2KDw63b7yEIa9Q2GXnbidL5Tk+s92BJX0XvYfHrv2l1fYE2vdRWGnyhvCWmUavyCeiOle5uMxM6QLOb2Q==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1"
|
||||
]
|
||||
},
|
||||
"tauri-plugin-system-info-api@2.0.8": {
|
||||
"integrity": "sha512-EFdLXNGp6Zu9SNsZCkU+55A8027OnrVw/TQrd0oJHgfZzs4qvm1iMmSvyid4MLftt33iZDhjCzxYijaaOxeKSg==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"tauri-plugin-system-info-api@2.0.8_typescript@5.6.3": {
|
||||
"integrity": "sha512-EFdLXNGp6Zu9SNsZCkU+55A8027OnrVw/TQrd0oJHgfZzs4qvm1iMmSvyid4MLftt33iZDhjCzxYijaaOxeKSg==",
|
||||
"dependencies": [
|
||||
"@tauri-apps/api@2.1.1",
|
||||
"valibot"
|
||||
]
|
||||
},
|
||||
"to-regex-range@5.0.1": {
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dependencies": [
|
||||
"is-number"
|
||||
]
|
||||
},
|
||||
"tsc-alias@1.8.10": {
|
||||
"integrity": "sha512-Ibv4KAWfFkFdKJxnWfVtdOmB0Zi1RJVxcbPGiCDsFpCQSsmpWyuzHG3rQyI5YkobWwxFPEyQfu1hdo4qLG2zPw==",
|
||||
"dependencies": [
|
||||
"chokidar",
|
||||
"commander",
|
||||
"globby",
|
||||
"mylas",
|
||||
"normalize-path",
|
||||
"plimit-lit"
|
||||
]
|
||||
},
|
||||
"typescript@5.6.3": {
|
||||
"integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="
|
||||
},
|
||||
"valibot@0.40.0_typescript@5.6.3": {
|
||||
"integrity": "sha512-XHKnaVtwHqxPwnGOsLrwka9CEaL7yNeLNp707OKv/bmT29GnPVdl6PxBOZ6BW7hF66/6QT6iVbOlnW7qVPmoKw==",
|
||||
"dependencies": [
|
||||
"typescript"
|
||||
]
|
||||
},
|
||||
"which@2.0.2": {
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dependencies": [
|
||||
"isexe"
|
||||
]
|
||||
},
|
||||
"wrap-ansi@7.0.0": {
|
||||
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
|
||||
"dependencies": [
|
||||
"ansi-styles@4.3.0",
|
||||
"string-width@4.2.3",
|
||||
"strip-ansi@6.0.1"
|
||||
]
|
||||
},
|
||||
"wrap-ansi@8.1.0": {
|
||||
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
|
||||
"dependencies": [
|
||||
"ansi-styles@6.2.1",
|
||||
"string-width@5.1.2",
|
||||
"strip-ansi@7.1.0"
|
||||
]
|
||||
},
|
||||
"wrappy@1.0.2": {
|
||||
"integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
|
||||
},
|
||||
"ws@8.18.0": {
|
||||
"integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="
|
||||
},
|
||||
"zimmerframe@1.1.2": {
|
||||
"integrity": "sha512-rAbqEGa8ovJy4pyBxZM70hg4pE6gDgaQ0Sl9M3enG3I0d6H4XSAM3GeNGLKnsBpuijUow064sf7ww1nutC5/3w=="
|
||||
}
|
||||
},
|
||||
"workspace": {
|
||||
"dependencies": [
|
||||
"jsr:@kunkun/api@^0.0.40",
|
||||
"jsr:@std/assert@1"
|
||||
]
|
||||
}
|
||||
}
|
7
deno-src/dev.ts
Normal file
7
deno-src/dev.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { readFirefoxBookmarks } from "./lib.ts"
|
||||
|
||||
const dbPath =
|
||||
"/Users/hacker/Library/Application Support/Firefox/Profiles/czahqvgw.default-release/places.sqlite"
|
||||
|
||||
const data = readFirefoxBookmarks(dbPath)
|
||||
console.log(data)
|
13
deno-src/index.ts
Normal file
13
deno-src/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { expose } from "@kunkun/api/runtime/deno"
|
||||
import { readFirefoxBookmarks } from "./lib.ts"
|
||||
|
||||
expose({
|
||||
readFirefoxBookmarks
|
||||
})
|
||||
// console.log(
|
||||
// readFirefoxBookmarks(
|
||||
// "/Users/hacker/Library/Application Support/Firefox/Profiles/czahqvgw.default-release/places.sqlite"
|
||||
// )
|
||||
// )
|
||||
|
||||
// deno run --allow-env=DENO_SQLITE_PATH,DENO_SQLITE_LOCAL,DENO_DIR,HOME --allow-read=/Users/hacker/Library/Caches/deno/plug --allow-ffi index.ts
|
21
deno-src/lib.ts
Normal file
21
deno-src/lib.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { Database } from "jsr:@db/sqlite@0.12.0"
|
||||
|
||||
export function readFirefoxBookmarks(dbPath: string) {
|
||||
const db = new Database(dbPath, { readonly: true })
|
||||
const stmt = db.prepare(`
|
||||
SELECT mb.title as name, mp.url as url, mp.title as title, mp.description as description, mp.preview_image_url as previewImageUrl
|
||||
FROM moz_bookmarks mb
|
||||
JOIN moz_places mp ON mb.fk = mp.id
|
||||
`)
|
||||
|
||||
const data = stmt.all<{
|
||||
name: string
|
||||
url: string
|
||||
title: string | null
|
||||
description: string | null
|
||||
previewImageUrl: string | null
|
||||
}>()
|
||||
|
||||
db.close()
|
||||
return data
|
||||
}
|
13
jsr.json
Normal file
13
jsr.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"name": "@kunkun/kunkun-ext-ip-info",
|
||||
"version": "0.0.3",
|
||||
"license": "MIT",
|
||||
"exports": "./mod.ts",
|
||||
"publish": {
|
||||
"include": ["dist", "deno-src", "README.md", "package.json", "mod.ts"]
|
||||
},
|
||||
"imports": {
|
||||
"@kunkun/api": "jsr:@kunkun/api@^0.0.52",
|
||||
"@std/assert": "jsr:@std/assert@1"
|
||||
}
|
||||
}
|
116
package.json
Normal file
116
package.json
Normal file
@ -0,0 +1,116 @@
|
||||
{
|
||||
"$schema": "https://schema.kunkun.sh",
|
||||
"license": "MIT",
|
||||
"name": "kunkun-ext-browser-bookmark",
|
||||
"version": "0.0.3",
|
||||
"repository": "https://github.com/kunkunsh/kunkun-ext-browser-bookmark",
|
||||
"type": "module",
|
||||
"kunkun": {
|
||||
"name": "Browser Bookmark",
|
||||
"shortDescription": "List Browser Bookmarks",
|
||||
"longDescription": "Show a list of Browser Bookmarks",
|
||||
"identifier": "browser-bookmark",
|
||||
"permissions": [
|
||||
"shell:stdin-write",
|
||||
"shell:kill",
|
||||
{
|
||||
"permission": "fs:read",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$HOME/Library/Application Support/Google/Chrome/Default/Bookmarks"
|
||||
},
|
||||
{
|
||||
"path": "$HOME/Library/Application Support/Microsoft Edge/Default/Bookmarks"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"permission": "fs:exists",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$HOME/Library/Application Support/Firefox/Profiles"
|
||||
},
|
||||
{
|
||||
"path": "$HOME/Library/Application Support/Firefox/Profiles/**"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"permission": "fs:read-dir",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$HOME/Library/Application Support/Firefox/Profiles"
|
||||
},
|
||||
{
|
||||
"path": "$HOME/Library/Application Support/Firefox/Profiles/**"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"permission": "open:url",
|
||||
"allow": [
|
||||
{
|
||||
"url": "http://**"
|
||||
},
|
||||
{
|
||||
"url": "https://**"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"permission": "shell:deno:spawn",
|
||||
"allow": [
|
||||
{
|
||||
"path": "$EXTENSION/deno-src/index.ts",
|
||||
"env": [
|
||||
"DENO_SQLITE_PATH",
|
||||
"DENO_SQLITE_LOCAL",
|
||||
"DENO_DIR",
|
||||
"HOME",
|
||||
"DENO_DENO"
|
||||
],
|
||||
"read": "*",
|
||||
"ffi": "*"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"demoImages": [],
|
||||
"icon": {
|
||||
"type": "iconify",
|
||||
"value": "material-symbols:bookmark"
|
||||
},
|
||||
"customUiCmds": [],
|
||||
"templateUiCmds": [
|
||||
{
|
||||
"name": "Browser Bookmarks",
|
||||
"main": "dist/index.js",
|
||||
"cmds": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "bun build.ts dev",
|
||||
"build": "bun build.ts"
|
||||
},
|
||||
"dependencies": {
|
||||
"@kksh/api": "^0.0.48",
|
||||
"i18next": "^23.15.1",
|
||||
"valibot": "^0.40.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "latest",
|
||||
"json-to-valibot": "^0.1.3"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"typescript": "^5.0.0"
|
||||
},
|
||||
"files": [
|
||||
"dist",
|
||||
"deno-src",
|
||||
"README.md",
|
||||
"package.json",
|
||||
"mod.ts"
|
||||
],
|
||||
"packageManager": "pnpm@9.14.2"
|
||||
}
|
263
src/bookmark.ts
Normal file
263
src/bookmark.ts
Normal file
@ -0,0 +1,263 @@
|
||||
import { fs, os, path, shell, toast } from "@kksh/api/ui/worker"
|
||||
import * as v from "valibot"
|
||||
import { ChromeBookmarksFile } from "./types"
|
||||
import type { Browser, ChromeBookmark, Platform } from "./types"
|
||||
|
||||
// given a url, compute it's favicon
|
||||
function getFavicon(url: string): string | undefined {
|
||||
if (!url.startsWith("http")) {
|
||||
return undefined
|
||||
}
|
||||
try {
|
||||
const urlObj = new URL(url)
|
||||
const faviconUrl = `${urlObj.protocol}//${urlObj.hostname}/favicon.ico`
|
||||
return faviconUrl
|
||||
} catch (error) {
|
||||
console.error("Failed to parse URL:", error)
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
export const FirefoxBookmark = v.object({
|
||||
name: v.string(),
|
||||
url: v.string(),
|
||||
title: v.nullable(v.string()),
|
||||
description: v.nullable(v.string()),
|
||||
previewImageUrl: v.nullable(v.string())
|
||||
})
|
||||
|
||||
export type FirefoxBookmark = v.InferOutput<typeof FirefoxBookmark>
|
||||
export const FirefoxBookmarkList = v.array(FirefoxBookmark)
|
||||
export type FirefoxBookmarkList = v.InferOutput<typeof FirefoxBookmarkList>
|
||||
|
||||
export type Bookmark = {
|
||||
name: string
|
||||
subtitle?: string
|
||||
url: string
|
||||
visitCount?: number
|
||||
favicon?: string
|
||||
}
|
||||
|
||||
export abstract class IBrowserBookmarks {
|
||||
protected bookmarkPath: string
|
||||
|
||||
constructor(bookmarkPath: string) {
|
||||
this.bookmarkPath = bookmarkPath
|
||||
}
|
||||
abstract load(): Promise<Bookmark[]>
|
||||
|
||||
getBookmarkPath(): string {
|
||||
return this.bookmarkPath
|
||||
}
|
||||
}
|
||||
|
||||
async function flattenChromeBookmarkTree(bookmarkTree: ChromeBookmark): Promise<Bookmark[]> {
|
||||
const bookmarks: Bookmark[] = []
|
||||
|
||||
if (bookmarkTree.type === "folder") {
|
||||
for (const child of bookmarkTree.children || []) {
|
||||
bookmarks.push(...(await flattenChromeBookmarkTree(child)))
|
||||
}
|
||||
} else if (bookmarkTree.type === "url" && bookmarkTree.url) {
|
||||
bookmarks.push({
|
||||
name: bookmarkTree.name,
|
||||
subtitle: bookmarkTree.name.trim().length === 0 ? bookmarkTree.url : undefined,
|
||||
url: bookmarkTree.url,
|
||||
visitCount: bookmarkTree.visit_count ?? 0,
|
||||
favicon: await getFavicon(bookmarkTree.url)
|
||||
})
|
||||
}
|
||||
return bookmarks
|
||||
}
|
||||
|
||||
export class ChromeBookmarks extends IBrowserBookmarks {
|
||||
async load(): Promise<Bookmark[]> {
|
||||
return fs
|
||||
.readTextFile(this.bookmarkPath)
|
||||
.then(async (content) => {
|
||||
try {
|
||||
const jsonParsed = JSON.parse(content)
|
||||
const parseResult = v.safeParse(ChromeBookmarksFile, jsonParsed)
|
||||
if (!parseResult.success) {
|
||||
throw new Error(`Failed to parse bookmark file: ${v.flatten(parseResult.issues)}`)
|
||||
}
|
||||
return [
|
||||
...(await flattenChromeBookmarkTree(parseResult.output.roots.bookmark_bar)),
|
||||
...(await flattenChromeBookmarkTree(parseResult.output.roots.other)),
|
||||
...(await flattenChromeBookmarkTree(parseResult.output.roots.synced))
|
||||
]
|
||||
.flat()
|
||||
.filter((b) => b.url || b.name)
|
||||
.sort((a, b) => (b.visitCount ?? 0) - (a.visitCount ?? 0))
|
||||
} catch (error) {
|
||||
toast.error(`Failed to parse bookmark file`, { description: this.bookmarkPath })
|
||||
throw new Error(`Failed to parse bookmark file: ${error}`)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
toast.error(`Failed to read bookmarks`, { description: err.message })
|
||||
return []
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export class FirefoxBookmarks extends IBrowserBookmarks {
|
||||
async load(): Promise<Bookmark[]> {
|
||||
const allowRead = await path.join(await path.homeDir(), "Library/Caches/deno/plug")
|
||||
const { rpcChannel, process, command } = await shell.createDenoRpcChannel<
|
||||
{},
|
||||
{
|
||||
readFirefoxBookmarks: (dbPath: string) => FirefoxBookmarkList
|
||||
}
|
||||
>(
|
||||
"$EXTENSION/deno-src/index.ts",
|
||||
[],
|
||||
{
|
||||
allowRead: [allowRead],
|
||||
allowEnv: ["DENO_SQLITE_PATH", "DENO_SQLITE_LOCAL", "DENO_DIR", "HOME"],
|
||||
allowAllFfi: true
|
||||
// allowNet: ["http://**", "https://**"]
|
||||
},
|
||||
{}
|
||||
)
|
||||
command.stderr.on("data", (data) => {
|
||||
console.error(data.toString())
|
||||
})
|
||||
const api = rpcChannel.getAPI()
|
||||
let bookmarks: Bookmark[] = []
|
||||
try {
|
||||
const rawFFBookmarks = await api.readFirefoxBookmarks(this.bookmarkPath)
|
||||
const parseResult = v.safeParse(FirefoxBookmarkList, rawFFBookmarks)
|
||||
if (!parseResult.success) {
|
||||
toast.error(`Failed to parse firefox bookmarks`)
|
||||
return []
|
||||
}
|
||||
bookmarks = parseResult.output.map((b) => ({
|
||||
name: b.name,
|
||||
subtitle: b.title ?? undefined,
|
||||
url: b.url,
|
||||
favicon: getFavicon(b.url)
|
||||
}))
|
||||
} catch (error) {
|
||||
} finally {
|
||||
process.kill()
|
||||
}
|
||||
return bookmarks
|
||||
}
|
||||
}
|
||||
|
||||
async function getChromeBookmarksPath(): Promise<string | null> {
|
||||
const platform: Platform = await os.platform()
|
||||
let bookmarkPath = null
|
||||
if (platform === "macos") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
"Library/Application Support/Google/Chrome/Default/Bookmarks"
|
||||
)
|
||||
} else if (platform === "linux") {
|
||||
bookmarkPath = await path.join(await path.homeDir(), ".config/google-chrome/Default/Bookmarks")
|
||||
} else if (platform === "windows") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
"AppData/Local/Google/Chrome/User Data/Default/Bookmarks"
|
||||
)
|
||||
}
|
||||
if (bookmarkPath && (await fs.exists(bookmarkPath))) {
|
||||
return bookmarkPath
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function getEdgeBookmarksPath(): Promise<string | null> {
|
||||
const platform: Platform = await os.platform()
|
||||
let bookmarkPath = null
|
||||
if (platform === "macos") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
"Library/Application Support/Microsoft Edge/Default/Bookmarks"
|
||||
)
|
||||
} else if (platform === "linux") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
".config/microsoft-edge-dev/Default/Bookmarks"
|
||||
)
|
||||
} else if (platform === "windows") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
"AppData/Local/Microsoft/Edge/User Data/Default/Bookmarks"
|
||||
)
|
||||
}
|
||||
if (bookmarkPath && (await fs.exists(bookmarkPath))) {
|
||||
return bookmarkPath
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
async function getFirefoxBookmarksPath(): Promise<string | null> {
|
||||
const platform: Platform = await os.platform()
|
||||
let bookmarkPath = null
|
||||
if (platform === "macos") {
|
||||
const firefoxProfilesDir = await path.join(
|
||||
await path.homeDir(),
|
||||
"Library/Application Support/Firefox/Profiles"
|
||||
)
|
||||
if (!(await fs.exists(firefoxProfilesDir))) {
|
||||
return null
|
||||
}
|
||||
const firefoxProfiles = await fs.readDir(firefoxProfilesDir)
|
||||
console.log("firefoxProfiles", firefoxProfiles)
|
||||
const defaultReleaseDir = firefoxProfiles.find((dir) => dir.name.includes("default-release"))
|
||||
if (!defaultReleaseDir) return null
|
||||
bookmarkPath = await path.join(firefoxProfilesDir, defaultReleaseDir.name, "places.sqlite")
|
||||
if (!(await fs.exists(bookmarkPath))) {
|
||||
console.warn("firefox bookmark DB not exists", bookmarkPath)
|
||||
return null
|
||||
}
|
||||
return bookmarkPath
|
||||
} else if (platform === "linux") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
"snap/firefox/common/.mozilla/firefox/vuolckoc.default/places.sqlite"
|
||||
)
|
||||
} else if (platform === "windows") {
|
||||
bookmarkPath = await path.join(
|
||||
await path.homeDir(),
|
||||
"AppData/Roaming/Mozilla/Firefox/Profiles/"
|
||||
)
|
||||
}
|
||||
if (bookmarkPath && (await fs.exists(bookmarkPath))) {
|
||||
return bookmarkPath
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
export async function createBookmarkLoader(browser: Browser): Promise<IBrowserBookmarks | null> {
|
||||
switch (browser) {
|
||||
case "chrome":
|
||||
const chromeBookmarkPath = await getChromeBookmarksPath()
|
||||
if (chromeBookmarkPath) {
|
||||
return new ChromeBookmarks(chromeBookmarkPath)
|
||||
}
|
||||
break
|
||||
case "edge":
|
||||
const edgeBookmarkPath = await getEdgeBookmarksPath()
|
||||
if (edgeBookmarkPath) {
|
||||
return new ChromeBookmarks(edgeBookmarkPath)
|
||||
}
|
||||
break
|
||||
case "firefox":
|
||||
const firefoxSqlitePath = await getFirefoxBookmarksPath()
|
||||
if (firefoxSqlitePath) {
|
||||
return new FirefoxBookmarks(firefoxSqlitePath)
|
||||
}
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
2
src/constants.ts
Normal file
2
src/constants.ts
Normal file
@ -0,0 +1,2 @@
|
||||
import type { Browser, Platform } from "./types";
|
||||
|
5
src/i18n/en.ts
Normal file
5
src/i18n/en.ts
Normal file
@ -0,0 +1,5 @@
|
||||
const en = {
|
||||
welcome: "Welcome to Kunkun"
|
||||
}
|
||||
export default en
|
||||
export type Translation = typeof en
|
20
src/i18n/index.ts
Normal file
20
src/i18n/index.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import i18next from "i18next"
|
||||
import en, { type Translation } from "./en"
|
||||
import zh from "./zh"
|
||||
|
||||
export function setupI18n(language: "en" | "zh" = "en") {
|
||||
i18next.init({
|
||||
resources: {
|
||||
en: {
|
||||
translation: en
|
||||
},
|
||||
zh: {
|
||||
translation: zh
|
||||
}
|
||||
},
|
||||
lng: language, // default language
|
||||
fallbackLng: "en"
|
||||
})
|
||||
}
|
||||
|
||||
export const t = (key: keyof Translation, options?: any) => i18next.t(key, options)
|
5
src/i18n/zh.ts
Normal file
5
src/i18n/zh.ts
Normal file
@ -0,0 +1,5 @@
|
||||
import type { Translation } from "./en"
|
||||
|
||||
export default {
|
||||
welcome: "欢迎来到Kunkun"
|
||||
} satisfies Translation
|
140
src/index.ts
Normal file
140
src/index.ts
Normal file
@ -0,0 +1,140 @@
|
||||
import {
|
||||
Action,
|
||||
app,
|
||||
expose,
|
||||
Form,
|
||||
fs,
|
||||
Icon,
|
||||
IconEnum,
|
||||
List,
|
||||
NodeNameEnum,
|
||||
open,
|
||||
os,
|
||||
path,
|
||||
shell,
|
||||
toast,
|
||||
ui,
|
||||
WorkerExtension
|
||||
} from "@kksh/api/ui/worker"
|
||||
import { ChromeBookmarks, createBookmarkLoader, type Bookmark } from "./bookmark"
|
||||
import { setupI18n, t } from "./i18n"
|
||||
import type { Platform } from "./types"
|
||||
|
||||
function bookmarkToItem(bookmark: Bookmark, options: { browserIcon: Icon }): List.Item {
|
||||
return new List.Item({
|
||||
title: bookmark.name,
|
||||
subTitle: bookmark.subtitle,
|
||||
value: bookmark.url,
|
||||
icon: bookmark.favicon
|
||||
? new Icon({
|
||||
type: IconEnum.RemoteUrl,
|
||||
value: bookmark.favicon
|
||||
})
|
||||
: new Icon({
|
||||
type: IconEnum.Iconify,
|
||||
value: options.browserIcon.value
|
||||
}),
|
||||
accessories: [
|
||||
new List.ItemAccessory({
|
||||
icon: new Icon({
|
||||
type: IconEnum.Iconify,
|
||||
value: options.browserIcon.value
|
||||
})
|
||||
})
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
class BrowserBookmark extends WorkerExtension {
|
||||
async onFormSubmit(value: Record<string, any>): Promise<void> {
|
||||
console.log("Form submitted", value)
|
||||
toast.success(`Form submitted: ${JSON.stringify(value)}`)
|
||||
}
|
||||
async load() {
|
||||
ui.showLoadingBar(true)
|
||||
ui.setSearchBarPlaceholder("Search for bookmarks")
|
||||
ui.render(new List.List({}))
|
||||
// const platform: Platform = await os.platform()
|
||||
const [chromeBookmarks, edgeBookmarks, firefoxBookmarks] = await Promise.all([
|
||||
createBookmarkLoader("chrome").then((loader) => loader?.load() ?? []),
|
||||
createBookmarkLoader("edge").then((loader) => loader?.load() ?? []),
|
||||
createBookmarkLoader("firefox").then((loader) => loader?.load() ?? [])
|
||||
])
|
||||
|
||||
const sections: List.Section[] = []
|
||||
|
||||
if (firefoxBookmarks.length > 0) {
|
||||
sections.push(
|
||||
new List.Section({
|
||||
title: "Firefox",
|
||||
subtitle: "Firefox",
|
||||
items: firefoxBookmarks.map((bookmark) =>
|
||||
bookmarkToItem(bookmark, {
|
||||
browserIcon: new Icon({ type: IconEnum.Iconify, value: "logos:firefox" })
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
if (chromeBookmarks.length > 0) {
|
||||
sections.push(
|
||||
new List.Section({
|
||||
title: "Chrome",
|
||||
subtitle: "Chrome",
|
||||
items: chromeBookmarks.map((bookmark) =>
|
||||
bookmarkToItem(bookmark, {
|
||||
browserIcon: new Icon({ type: IconEnum.Iconify, value: "logos:chrome" })
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
if (edgeBookmarks.length > 0) {
|
||||
sections.push(
|
||||
new List.Section({
|
||||
title: "Edge",
|
||||
subtitle: "Edge",
|
||||
items: edgeBookmarks.map((bookmark) =>
|
||||
bookmarkToItem(bookmark, {
|
||||
browserIcon: new Icon({ type: IconEnum.Iconify, value: "logos:microsoft-edge" })
|
||||
})
|
||||
)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return ui
|
||||
.setSearchBarPlaceholder("Enter a search term, and press enter to search")
|
||||
.then(async () => {
|
||||
return ui.render(new List.List({ sections }))
|
||||
})
|
||||
.finally(() => {
|
||||
ui.showLoadingBar(false)
|
||||
})
|
||||
}
|
||||
|
||||
async onActionSelected(actionValue: string): Promise<void> {
|
||||
switch (actionValue) {
|
||||
case "open":
|
||||
break
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onSearchTermChange(term: string): Promise<void> {
|
||||
return Promise.resolve()
|
||||
}
|
||||
|
||||
onListItemSelected(value: string): Promise<void> {
|
||||
console.log("Item selected:", value)
|
||||
if (value.startsWith("http")) {
|
||||
open.url(value)
|
||||
}
|
||||
return Promise.resolve()
|
||||
}
|
||||
}
|
||||
|
||||
expose(new BrowserBookmark())
|
42
src/types.ts
Normal file
42
src/types.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { os } from "@kksh/api/ui/worker"
|
||||
import * as v from "valibot"
|
||||
|
||||
export type Platform = Awaited<ReturnType<typeof os.platform>>
|
||||
export type Browser = "chrome" | "firefox" | "edge"
|
||||
|
||||
export type ChromeBookmark = {
|
||||
date_added: string
|
||||
date_last_used: string
|
||||
guid: string
|
||||
id: string
|
||||
name: string
|
||||
type: "url" | "folder"
|
||||
url?: string
|
||||
children?: ChromeBookmark[]
|
||||
visit_count?: number
|
||||
}
|
||||
|
||||
export const ChromeBookmark: v.GenericSchema<ChromeBookmark> = v.object({
|
||||
date_added: v.string(),
|
||||
date_last_used: v.string(),
|
||||
guid: v.string(),
|
||||
id: v.string(),
|
||||
name: v.string(),
|
||||
type: v.union([v.literal("url"), v.literal("folder")]),
|
||||
url: v.optional(v.string()),
|
||||
visit_count: v.optional(v.number()),
|
||||
children: v.optional(v.array(v.lazy(() => ChromeBookmark)))
|
||||
})
|
||||
|
||||
export const ChromeBookmarksFile = v.object({
|
||||
checksum: v.string(),
|
||||
version: v.number(),
|
||||
sync_metadata: v.string(),
|
||||
roots: v.object({
|
||||
bookmark_bar: ChromeBookmark,
|
||||
other: ChromeBookmark,
|
||||
synced: ChromeBookmark
|
||||
})
|
||||
})
|
||||
|
||||
export type ChromeBookmarksFile = v.InferOutput<typeof ChromeBookmarksFile>
|
27
tsconfig.json
Normal file
27
tsconfig.json
Normal file
@ -0,0 +1,27 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
// Enable latest features
|
||||
"lib": [
|
||||
"ESNext",
|
||||
"DOM"
|
||||
],
|
||||
"target": "ESNext",
|
||||
"module": "ESNext",
|
||||
"moduleDetection": "force",
|
||||
"jsx": "react-jsx",
|
||||
"allowJs": true,
|
||||
// Bundler mode
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": false,
|
||||
"verbatimModuleSyntax": true,
|
||||
"noEmit": true,
|
||||
// Best practices
|
||||
"strict": true,
|
||||
"skipLibCheck": true,
|
||||
"noFallthroughCasesInSwitch": true,
|
||||
// Some stricter flags (disabled by default)
|
||||
"noUnusedLocals": false,
|
||||
"noUnusedParameters": false,
|
||||
"noPropertyAccessFromIndexSignature": false
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user