diff --git a/bun.config.ts b/bun.config.ts index 5ad486a..fd5b76e 100644 --- a/bun.config.ts +++ b/bun.config.ts @@ -8,6 +8,7 @@ for (const query of queryList) { naming: query.name, entry: `query/${query.name}/index.ts`, meta: import.meta, + target: 'browser', dts: true, }) } \ No newline at end of file diff --git a/package.json b/package.json index 38581bc..3bda8a4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@kevisual/api", - "version": "0.0.47", + "version": "0.0.48", "description": "", "main": "mod.ts", "scripts": { @@ -17,22 +17,22 @@ "keywords": [], "author": "abearxiong (https://www.xiongxiao.me)", "license": "MIT", - "packageManager": "pnpm@10.28.2", + "packageManager": "pnpm@10.29.3", "type": "module", "devDependencies": { "@kevisual/cache": "^0.0.5", "@kevisual/code-builder": "^0.0.6", - "@kevisual/query": "^0.0.39", + "@kevisual/query": "^0.0.40", "@kevisual/remote-app": "^0.0.4", "@kevisual/router": "^0.0.70", "@kevisual/types": "^0.0.12", "@kevisual/use-config": "^1.0.30", - "@types/bun": "^1.3.8", + "@types/bun": "^1.3.9", "@types/crypto-js": "^4.2.2", - "@types/node": "^25.2.0", + "@types/node": "^25.2.3", "@types/spark-md5": "^3.0.5", "crypto-js": "^4.2.0", - "dotenv": "^17.2.3", + "dotenv": "^17.3.1", "fast-glob": "^3.3.3", "ws": "npm:@kevisual/ws" }, @@ -55,6 +55,7 @@ "./secret": "./query/query-secret/index.ts", "./resources": "./query/query-resources/index.ts", "./query-secret": "./dist/query-secret.js", + "./query-mark": "./dist/query-mark.js", "./utils": "./dist/utils.js", "./query-upload": "./dist/query-upload.js", "./query-app": "./dist/query-app.js", @@ -63,6 +64,8 @@ "./query-config": "./dist/query-config.js", "./query-login": "./dist/query-login.js", "./query-ai": "./dist/query-ai.js", - "./query-resources": "./dist/query-resources.js" + "./query-resources": "./dist/query-resources.js", + "./src/*": "./src/*", + "./query/*": "./query/*" } } \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a05965e..1ddfd01 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -40,8 +40,8 @@ importers: specifier: ^0.0.6 version: 0.0.6 '@kevisual/query': - specifier: ^0.0.39 - version: 0.0.39 + specifier: ^0.0.40 + version: 0.0.40 '@kevisual/remote-app': specifier: ^0.0.4 version: 0.0.4 @@ -53,16 +53,16 @@ importers: version: 0.0.12 '@kevisual/use-config': specifier: ^1.0.30 - version: 1.0.30(dotenv@17.2.3) + version: 1.0.30(dotenv@17.3.1) '@types/bun': - specifier: ^1.3.8 - version: 1.3.8 + specifier: ^1.3.9 + version: 1.3.9 '@types/crypto-js': specifier: ^4.2.2 version: 4.2.2 '@types/node': - specifier: ^25.2.0 - version: 25.2.0 + specifier: ^25.2.3 + version: 25.2.3 '@types/spark-md5': specifier: ^3.0.5 version: 3.0.5 @@ -70,8 +70,8 @@ importers: specifier: ^4.2.0 version: 4.2.0 dotenv: - specifier: ^17.2.3 - version: 17.2.3 + specifier: ^17.3.1 + version: 17.3.1 fast-glob: specifier: ^3.3.3 version: 3.3.3 @@ -117,8 +117,8 @@ packages: '@kevisual/query@0.0.18': resolution: {integrity: sha512-I2vHTu0I6AyD9PJyr+vxyp9jIJ6rd2EZqLVHTv/+zrVKVc2SS76Tg7aGNkmAFqqLSCB8kLLsmMGtSJU1Qb8VVg==} - '@kevisual/query@0.0.39': - resolution: {integrity: sha512-3UEPBIvtdykNkrby3hvrgrHdgd17Uq+Pnr4zs+JBzATkU2eKaOqtTUJqdyIEwuySCwzGTxrnlUzWP4tziDQDLQ==} + '@kevisual/query@0.0.40': + resolution: {integrity: sha512-7m5BgDzd01m51hCHUId6ugQHdwgrLTb6fI7DSuMY17VjWb0+zGnkYmvRBqkTXzoIjjYbP5iwtRnrooEoToQfhg==} '@kevisual/remote-app@0.0.4': resolution: {integrity: sha512-2yIlWY98pLCcxG+DJsqXXkd5YYEgymuOsyElH+31AoEPb7mlNREnYS81zN0KM9nvdSmU2G51vV4UVirJlYBZCQ==} @@ -156,8 +156,8 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@types/bun@1.3.8': - resolution: {integrity: sha512-3LvWJ2q5GerAXYxO2mffLTqOzEu5qnhEAlh48Vnu8WQfnmSwbgagjGZV6BoHKJztENYEDn6QmVd949W4uESRJA==} + '@types/bun@1.3.9': + resolution: {integrity: sha512-KQ571yULOdWJiMH+RIWIOZ7B2RXQGpL1YQrBtLIV3FqDcCu6FsbFUBwhdKUlCKUpS3PJDsHlJ1QKlpxoVR+xtw==} '@types/crypto-js@4.2.2': resolution: {integrity: sha512-sDOLlVbHhXpAUAL0YHDUUwDZf3iN4Bwi4W6a0W0b+QcAezUbRtH4FVb+9J4h+XFPW7l/gQ9F8qC7P+Ec4k8QVQ==} @@ -174,8 +174,8 @@ packages: '@types/node@22.15.27': resolution: {integrity: sha512-5fF+eu5mwihV2BeVtX5vijhdaZOfkQTATrePEaXTcKqI16LhJ7gi2/Vhd9OZM0UojcdmiOCVg5rrax+i1MdoQQ==} - '@types/node@25.2.0': - resolution: {integrity: sha512-DZ8VwRFUNzuqJ5khrvwMXHmvPe+zGayJhr2CDNiKB1WBE1ST8Djl00D0IC4vvNmHMdj6DlbYRIaFE7WHjlDl5w==} + '@types/node@25.2.3': + resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} '@types/spark-md5@3.0.5': resolution: {integrity: sha512-lWf05dnD42DLVKQJZrDHtWFidcLrHuip01CtnC2/S6AMhX4t9ZlEUj4iuRlAnts0PQk7KESOqKxeGE/b6sIPGg==} @@ -195,8 +195,8 @@ packages: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - bun-types@1.3.8: - resolution: {integrity: sha512-fL99nxdOWvV4LqjmC+8Q9kW3M4QTtTR1eePs94v5ctGqU8OeceWrSUaRw3JYb7tU3FkMIAjkueehrHPPPGKi5Q==} + bun-types@1.3.9: + resolution: {integrity: sha512-+UBWWOakIP4Tswh0Bt0QD0alpTY8cb5hvgiYeWCMet9YukHbzuruIEeXC2D7nMJPB12kbh8C7XJykSexEqGKJg==} call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} @@ -213,8 +213,8 @@ packages: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dotenv@17.2.3: - resolution: {integrity: sha512-JVUnt+DUIzu87TABbhPmNfVdBDt18BLOWjMUFJMSi/Qqg7NTYtabbvSNJGOJ7afbRuv9D/lngizHtP7QyLQ+9w==} + dotenv@17.3.1: + resolution: {integrity: sha512-IO8C/dzEb6O3F9/twg6ZLXz164a2fhTnEWb95H23Dm4OuN+92NmEAlTrupP9VW6Jm3sO26tQlqyvyi4CsnY9GA==} engines: {node: '>=12'} dunder-proto@1.0.1: @@ -465,7 +465,7 @@ snapshots: - ws - zod - '@kevisual/query@0.0.39': + '@kevisual/query@0.0.40': dependencies: tslib: 2.8.1 @@ -484,10 +484,10 @@ snapshots: '@kevisual/types@0.0.12': {} - '@kevisual/use-config@1.0.30(dotenv@17.2.3)': + '@kevisual/use-config@1.0.30(dotenv@17.3.1)': dependencies: '@kevisual/load': 0.0.6 - dotenv: 17.2.3 + dotenv: 17.3.1 '@kevisual/ws@8.19.0': {} @@ -503,9 +503,9 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.19.1 - '@types/bun@1.3.8': + '@types/bun@1.3.9': dependencies: - bun-types: 1.3.8 + bun-types: 1.3.9 '@types/crypto-js@4.2.2': {} @@ -526,7 +526,7 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@25.2.0': + '@types/node@25.2.3': dependencies: undici-types: 7.16.0 @@ -546,9 +546,9 @@ snapshots: dependencies: fill-range: 7.1.1 - bun-types@1.3.8: + bun-types@1.3.9: dependencies: - '@types/node': 25.2.0 + '@types/node': 25.2.3 call-bind-apply-helpers@1.0.2: dependencies: @@ -563,7 +563,7 @@ snapshots: delayed-stream@1.0.0: {} - dotenv@17.2.3: {} + dotenv@17.3.1: {} dunder-proto@1.0.1: dependencies: diff --git a/query/query-mark/index.ts b/query/query-mark/index.ts new file mode 100644 index 0000000..1d58692 --- /dev/null +++ b/query/query-mark/index.ts @@ -0,0 +1,154 @@ +import { Query } from '@kevisual/query'; +import type { Result, DataOpts } from '@kevisual/query/query'; + +export type SimpleObject = Record; +export const markType = ['simple', 'md', 'mdx', 'wallnote', 'excalidraw', 'chat'] as const; +export type MarkType = (typeof markType)[number]; +export type MarkData = { + nodes?: any[]; + edges?: any[]; + elements?: any[]; + permission?: any; + + [key: string]: any; +}; +export type Mark = { + id: string; + title: string; + description: string; + markType: MarkType; + link: string; + data?: MarkData; + uid: string; + puid: string; + summary: string; + thumbnail?: string; + tags: string[]; + createdAt: string; + updatedAt: string; + version: number; +}; +export type ShowMarkPick = Pick; + +export type SearchOpts = { + page?: number; + pageSize?: number; + search?: string; + sort?: string; // DESC, ASC + markType?: MarkType; // 类型 + [key: string]: any; +}; + +export type QueryMarkOpts = { + query?: Query; + isBrowser?: boolean; + onLoad?: () => void; +} & T; + +export type ResultMarkList = { + list: Mark[]; + pagination: { + pageSize: number; + current: number; + total: number; + }; +}; +export type QueryMarkData = { + id?: string; + title?: string; + description?: string; + [key: string]: any; +}; +export type QueryMarkResult = { + accessToken: string; + refreshToken: string; +}; + +export class QueryMarkBase { + query: Query; + isBrowser: boolean; + load?: boolean; + storage?: Storage; + onLoad?: () => void; + + constructor(opts?: QueryMarkOpts) { + this.query = opts?.query || new Query(); + this.isBrowser = opts?.isBrowser ?? true; + this.init(); + this.onLoad = opts?.onLoad; + } + setQuery(query: Query) { + this.query = query; + } + private async init() { + this.load = true; + this.onLoad?.(); + } + + async post>(data: any, opts?: DataOpts): Promise { + try { + return this.query.post({ path: 'mark', ...data }, opts) as Promise; + } catch (error) { + console.log('error', error); + return { + code: 400, + } as any; + } + } + + async getMarkList(search: SearchOpts, opts?: DataOpts) { + return this.post>({ key: 'list', ...search }, opts); + } + + async getMark(id: string, opts?: DataOpts) { + return this.post>({ key: 'get', id }, opts); + } + async getVersion(id: string, opts?: DataOpts) { + return this.post>({ key: 'getVersion', id }, opts); + } + /** + * 检查版本 + * 当需要更新时,返回true + * @param id + * @param version + * @param opts + * @returns + */ + async checkVersion(id: string, version?: number, opts?: DataOpts) { + if (!version) { + return true; + } + const res = await this.getVersion(id, opts); + if (res.code === 200) { + if (res.data!.version > version) { + return true; + } + return false; + } + return true; + } + + async updateMark(data: any, opts?: DataOpts) { + return this.post>({ key: 'update', data }, opts); + } + + async deleteMark(id: string, opts?: DataOpts) { + return this.post>({ key: 'delete', id }, opts); + } +} +export class QueryMark extends QueryMarkBase { + markType: string; + constructor(opts?: QueryMarkOpts & { markType?: MarkType }) { + super(opts); + this.markType = opts?.markType || 'simple'; + } + async getMarkList(search?: SearchOpts, opts?: DataOpts) { + return this.post>({ key: 'list', ...search, markType: this.markType }, opts); + } + async updateMark(data: any, opts?: DataOpts) { + if (!data.id) { + data.markType = this.markType || 'simple'; + } + return super.updateMark(data, opts); + } +} diff --git a/query/query-resources/utils.ts b/query/query-resources/utils.ts index 92cc7ca..2c778d6 100644 --- a/query/query-resources/utils.ts +++ b/query/query-resources/utils.ts @@ -1,13 +1,12 @@ -import MD5 from 'crypto-js/md5'; import SparkMD5 from 'spark-md5'; export const hashContent = (str: string | Blob | Buffer): Promise | string => { if (typeof str === 'string') { - return MD5(str).toString(); + return SparkMD5.hash(str); } else if (str instanceof Blob) { return hashBlob(str); } else if (Buffer.isBuffer(str)) { - return MD5(str.toString()).toString(); + return SparkMD5.hash(str.toString()); } console.error('hashContent error: input must be a string, Blob, or Buffer'); return '';