diff --git a/.opencode/plugin/agent.ts b/.opencode/plugin/agent.ts new file mode 100644 index 0000000..999ca5e --- /dev/null +++ b/.opencode/plugin/agent.ts @@ -0,0 +1,3 @@ +import { browserAgentPlugin } from './../../src/index.ts'; + +export { browserAgentPlugin } \ No newline at end of file diff --git a/package.json b/package.json index 7e928f9..f121a45 100644 --- a/package.json +++ b/package.json @@ -37,33 +37,35 @@ ], "author": "abearxiong (https://www.xiongxiao.me)", "license": "MIT", - "packageManager": "pnpm@10.26.0", + "packageManager": "pnpm@10.28.1", "type": "module", "dependencies": { - "better-sqlite3": "^12.5.0", + "better-sqlite3": "^12.6.2", + "nanoid": "^5.1.6", "playwright": "^1.57.0", "playwright-extra": "^4.3.6", "playwright-extra-plugin-stealth": "^0.0.1", "user-agents": "^1.1.669", - "zod": "^4.2.1", + "zod": "^4.3.5", "zod-to-json-schema": "^3.25.1" }, "devDependencies": { - "@kevisual/code-builder": "^0.0.2", + "@kevisual/code-builder": "^0.0.3", "@kevisual/context": "^0.0.4", - "@kevisual/router": "^0.0.49", - "@kevisual/types": "^0.0.10", - "@kevisual/use-config": "^1.0.21", + "@kevisual/js-filter": "^0.0.5", + "@kevisual/router": "^0.0.59", "@types/better-sqlite3": "^7.6.13", - "@types/bun": "^1.3.5", - "@types/node": "^25.0.3", + "@kevisual/types": "^0.0.11", + "@kevisual/use-config": "^1.0.28", + "@types/bun": "^1.3.6", + "@types/node": "^25.0.9", "@types/user-agents": "^1.0.4", "commander": "^14.0.2", "dotenv": "^17.2.3", "drizzle-kit": "^0.31.8", "drizzle-orm": "^0.45.1", - "es-toolkit": "^1.43.0", - "eventemitter3": "^5.0.1", + "es-toolkit": "^1.44.0", + "eventemitter3": "^5.0.4", "lru-cache": "^11.2.4", "puppeteer-extra-plugin-stealth": "^2.11.2" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fd7ac48..bce8f21 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,11 @@ importers: .: dependencies: better-sqlite3: - specifier: ^12.5.0 - version: 12.5.0 + specifier: ^12.6.2 + version: 12.6.2 + nanoid: + specifier: ^5.1.6 + version: 5.1.6 playwright: specifier: ^1.57.0 version: 1.57.0 @@ -24,36 +27,39 @@ importers: specifier: ^1.1.669 version: 1.1.669 zod: - specifier: ^4.2.1 - version: 4.2.1 + specifier: ^4.3.5 + version: 4.3.5 zod-to-json-schema: specifier: ^3.25.1 - version: 3.25.1(zod@4.2.1) + version: 3.25.1(zod@4.3.5) devDependencies: '@kevisual/code-builder': - specifier: ^0.0.2 - version: 0.0.2(dotenv@17.2.3) + specifier: ^0.0.3 + version: 0.0.3 '@kevisual/context': specifier: ^0.0.4 version: 0.0.4 + '@kevisual/js-filter': + specifier: ^0.0.5 + version: 0.0.5 '@kevisual/router': - specifier: ^0.0.49 - version: 0.0.49 + specifier: ^0.0.59 + version: 0.0.59 '@kevisual/types': - specifier: ^0.0.10 - version: 0.0.10 + specifier: ^0.0.11 + version: 0.0.11 '@kevisual/use-config': - specifier: ^1.0.21 - version: 1.0.21(dotenv@17.2.3) + specifier: ^1.0.28 + version: 1.0.28(dotenv@17.2.3) '@types/better-sqlite3': specifier: ^7.6.13 version: 7.6.13 '@types/bun': - specifier: ^1.3.5 - version: 1.3.5 + specifier: ^1.3.6 + version: 1.3.6 '@types/node': - specifier: ^25.0.3 - version: 25.0.3 + specifier: ^25.0.9 + version: 25.0.9 '@types/user-agents': specifier: ^1.0.4 version: 1.0.4 @@ -68,13 +74,13 @@ importers: version: 0.31.8 drizzle-orm: specifier: ^0.45.1 - version: 0.45.1(@types/better-sqlite3@7.6.13)(better-sqlite3@12.5.0)(bun-types@1.3.5) + version: 0.45.1(@types/better-sqlite3@7.6.13)(better-sqlite3@12.6.2)(bun-types@1.3.6) es-toolkit: - specifier: ^1.43.0 - version: 1.43.0 + specifier: ^1.44.0 + version: 1.44.0 eventemitter3: - specifier: ^5.0.1 - version: 5.0.1 + specifier: ^5.0.4 + version: 5.0.4 lru-cache: specifier: ^11.2.4 version: 11.2.4 @@ -383,70 +389,35 @@ packages: cpu: [x64] os: [win32] - '@kevisual/code-builder@0.0.2': - resolution: {integrity: sha512-SJAYfPqoK/TsjFj1JyUrr7Ac+Q5PjpXIK3BupVH9XJLVqy5ADgnHEuHDcYb0dRsea5KJ+k2XTPchCEIImRo4yw==} + '@kevisual/code-builder@0.0.3': + resolution: {integrity: sha512-mw8HMYBI9otzBv0ASB/Rqb9g03NxpXlR97ScaLb5xeQFNwO/ohdrLdwuNohUBIzLosMWUkuTGIBzV63UhlgIvw==} hasBin: true '@kevisual/context@0.0.4': resolution: {integrity: sha512-HJeLeZQLU+7tCluSfOyvkgKLs0HjCZrdJlZgEgKRSa8XTwZfMAUt6J7qZTbrZAHBlPtX68EPu/PI8JMCeu3WAQ==} + '@kevisual/js-filter@0.0.5': + resolution: {integrity: sha512-+S+Sf3K/aP6XtZI2s7TgKOr35UuvUvtpJ9YDW30a+mY0/N8gRuzyKhieBzQN7Ykayzz70uoMavBXut2rUlLgzw==} + '@kevisual/load@0.0.6': resolution: {integrity: sha512-+3YTFehRcZ1haGel5DKYMUwmi5i6f2psyaPZlfkKU/cOXgkpwoG9/BEqPCnPjicKqqnksEpixVRkyHJ+5bjLVA==} - '@kevisual/router@0.0.49': - resolution: {integrity: sha512-2HXuOnnWdRfkO0LyqolWU9cvWHGXi8FV3OqEvWgfO+f7wx8GT8T6Bb8dCzdldDaAxve1dgLBavtdmnHyCkp+1Q==} + '@kevisual/router@0.0.59': + resolution: {integrity: sha512-XMKznfUAXVlycPdZOmOOgjhKkdJlD8+gMJzJ/Xi2ouOPDjGaxM4qPHexamUPQrvCeImZX4fwPG6lqGq3fbWY1w==} - '@kevisual/types@0.0.10': - resolution: {integrity: sha512-Q73uzzjk9UidumnmCvOpgzqDDvQxsblz22bIFuoiioUFJWwaparx8bpd8ArRyFojicYL1YJoFDzDZ9j9NN8grA==} + '@kevisual/types@0.0.11': + resolution: {integrity: sha512-idNLDTEKVdNXZHFQq8PTN62nflh94kvGtx+v8YDcMxt0Zo+HWVZTFElm+dMQxAs/vn4wo8F2r3VwzWNX/vcqwQ==} - '@kevisual/use-config@1.0.21': - resolution: {integrity: sha512-czgy4+tBDBJI6QTnKh2PCwswET6ZpZ4ZqBE/SPkkOivEtlrcPzLs5elwMLZ3goD1XMD4VB3yjumb5WuW/8H8MA==} + '@kevisual/use-config@1.0.28': + resolution: {integrity: sha512-ngF+LDbjxpXWrZNmnShIKF/jPpAa+ezV+DcgoZIIzHlRnIjE+rr9sLkN/B7WJbiH9C/j1tQXOILY8ujBqILrow==} peerDependencies: dotenv: ^17 - '@noble/hashes@1.4.0': - resolution: {integrity: sha512-V1JJ1WTRUqHHrOSh597hURcMqVKVGL/ea3kv0gSnEdsEZ0/+VyPghM1lMNGc00z7CIQorSvbKpuJkxvuHbvdbg==} - engines: {node: '>= 16'} - - '@peculiar/asn1-cms@2.6.0': - resolution: {integrity: sha512-2uZqP+ggSncESeUF/9Su8rWqGclEfEiz1SyU02WX5fUONFfkjzS2Z/F1Li0ofSmf4JqYXIOdCAZqIXAIBAT1OA==} - - '@peculiar/asn1-csr@2.6.0': - resolution: {integrity: sha512-BeWIu5VpTIhfRysfEp73SGbwjjoLL/JWXhJ/9mo4vXnz3tRGm+NGm3KNcRzQ9VMVqwYS2RHlolz21svzRXIHPQ==} - - '@peculiar/asn1-ecc@2.6.0': - resolution: {integrity: sha512-FF3LMGq6SfAOwUG2sKpPXblibn6XnEIKa+SryvUl5Pik+WR9rmRA3OCiwz8R3lVXnYnyRkSZsSLdml8H3UiOcw==} - - '@peculiar/asn1-pfx@2.6.0': - resolution: {integrity: sha512-rtUvtf+tyKGgokHHmZzeUojRZJYPxoD/jaN1+VAB4kKR7tXrnDCA/RAWXAIhMJJC+7W27IIRGe9djvxKgsldCQ==} - - '@peculiar/asn1-pkcs8@2.6.0': - resolution: {integrity: sha512-KyQ4D8G/NrS7Fw3XCJrngxmjwO/3htnA0lL9gDICvEQ+GJ+EPFqldcJQTwPIdvx98Tua+WjkdKHSC0/Km7T+lA==} - - '@peculiar/asn1-pkcs9@2.6.0': - resolution: {integrity: sha512-b78OQ6OciW0aqZxdzliXGYHASeCvvw5caqidbpQRYW2mBtXIX2WhofNXTEe7NyxTb0P6J62kAAWLwn0HuMF1Fw==} - - '@peculiar/asn1-rsa@2.6.0': - resolution: {integrity: sha512-Nu4C19tsrTsCp9fDrH+sdcOKoVfdfoQQ7S3VqjJU6vedR7tY3RLkQ5oguOIB3zFW33USDUuYZnPEQYySlgha4w==} - - '@peculiar/asn1-schema@2.6.0': - resolution: {integrity: sha512-xNLYLBFTBKkCzEZIw842BxytQQATQv+lDTCEMZ8C196iJcJJMBUZxrhSTxLaohMyKK8QlzRNTRkUmanucnDSqg==} - - '@peculiar/asn1-x509-attr@2.6.0': - resolution: {integrity: sha512-MuIAXFX3/dc8gmoZBkwJWxUWOSvG4MMDntXhrOZpJVMkYX+MYc/rUAU2uJOved9iJEoiUx7//3D8oG83a78UJA==} - - '@peculiar/asn1-x509@2.6.0': - resolution: {integrity: sha512-uzYbPEpoQiBoTq0/+jZtpM6Gq6zADBx+JNFP3yqRgziWBxQ/Dt/HcuvRfm9zJTPdRcBqPNdaRHTVwpyiq6iNMA==} - - '@peculiar/x509@1.14.2': - resolution: {integrity: sha512-r2w1Hg6pODDs0zfAKHkSS5HLkOLSeburtcgwvlLLWWCixw+MmW3U6kD5ddyvc2Y2YdbGuVwCF2S2ASoU1cFAag==} - engines: {node: '>=22.0.0'} - '@types/better-sqlite3@7.6.13': resolution: {integrity: sha512-NMv9ASNARoKksWtsq/SHakpYAYnhBrQgGD8zkLYk/jaK8jUGn08CfEdTRgYhMypUQAfzSP8W6gNLe0q19/t4VA==} - '@types/bun@1.3.5': - resolution: {integrity: sha512-RnygCqNrd3srIPEWBd5LFeUYG7plCoH2Yw9WaZGyNmdTEei+gWaHqydbaIRkIkcbXwhBT94q78QljxN0Sk838w==} + '@types/bun@1.3.6': + resolution: {integrity: sha512-uWCv6FO/8LcpREhenN1d1b6fcspAB+cefwD7uti8C8VffIv0Um08TKMn98FynpTiU38+y2dUO55T11NgDt8VAA==} '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} @@ -454,8 +425,8 @@ packages: '@types/ms@2.1.0': resolution: {integrity: sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==} - '@types/node@25.0.3': - resolution: {integrity: sha512-W609buLVRVmeW693xKfzHeIV6nJGGz98uCPfeXI1ELMLXVeKYZ9m15fAMSaUPBHYLGFsVRcMmSCksQOrZV9BYA==} + '@types/node@25.0.9': + resolution: {integrity: sha512-/rpCXHlCWeqClNBwUhDcusJxXYDjZTyE8v5oTO7WbL8eij2nKhUeU89/6xgjU7N4/Vh3He0BtyhJdQbDyhiXAw==} '@types/user-agents@1.0.4': resolution: {integrity: sha512-AjeFc4oX5WPPflgKfRWWJfkEk7Wu82fnj1rROPsiqFt6yElpdGFg8Srtm/4PU4rA9UiDUZlruGPgcwTMQlwq4w==} @@ -464,18 +435,14 @@ packages: resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} engines: {node: '>=0.10.0'} - asn1js@3.0.7: - resolution: {integrity: sha512-uLvq6KJu04qoQM6gvBfKFjlh6Gl0vOKQuR5cJMDHQkmwfMOQeN3F3SHCv9SNYSL+CRoHvOGFfllDlVz03GQjvQ==} - engines: {node: '>=12.0.0'} - balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - better-sqlite3@12.5.0: - resolution: {integrity: sha512-WwCZ/5Diz7rsF29o27o0Gcc1Du+l7Zsv7SYtVPG0X3G/uUI1LqdxrQI7c9Hs2FWpqXXERjW9hp6g3/tH7DlVKg==} + better-sqlite3@12.6.2: + resolution: {integrity: sha512-8VYKM3MjCa9WcaSAI3hzwhmyHVlH8tiGFwf0RlTsZPWJ1I5MkzjiudCo4KC4DxOaL/53A5B1sI/IbldNFDbsKA==} engines: {node: 20.x || 22.x || 23.x || 24.x || 25.x} bindings@1.5.0: @@ -493,12 +460,8 @@ packages: buffer@5.7.1: resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - bun-types@1.3.5: - resolution: {integrity: sha512-inmAYe2PFLs0SUbFOWSVD24sg1jFlMPxOjOSSCYqUgn4Hsc3rDc7dFvfVYjFPNHtov6kgUeulV4SxbuIV/stPw==} - - bytestreamjs@2.0.1: - resolution: {integrity: sha512-U1Z/ob71V/bXfVABvNr/Kumf5VyeQRBEm6Txb0PQ6S7V5GpBM3w4Cbqz/xPDicR5tN0uvDifng8C+5qECeGwyQ==} - engines: {node: '>=6.0.0'} + bun-types@1.3.6: + resolution: {integrity: sha512-OlFwHcnNV99r//9v5IIOgQ9Uk37gZqrNMCcqEaExdkVq3Avwqok1bJFmvGMCkCE0FqzdY8VMOZpfpR3lwI+CsQ==} chownr@1.1.4: resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} @@ -535,10 +498,6 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} - depd@2.0.0: - resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} - engines: {node: '>= 0.8'} - detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} @@ -643,18 +602,11 @@ packages: sqlite3: optional: true - ee-first@1.1.1: - resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} - - encodeurl@2.0.0: - resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} - engines: {node: '>= 0.8'} - end-of-stream@1.4.5: resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - es-toolkit@1.43.0: - resolution: {integrity: sha512-SKCT8AsWvYzBBuUqMk4NPwFlSdqLpJwmy6AP322ERn8W2YLIB6JBXnwMI2Qsh2gfphT3q7EKAxKb23cvFHFwKA==} + es-toolkit@1.44.0: + resolution: {integrity: sha512-6penXeZalaV88MM3cGkFZZfOoLGWshWWfdy0tWw/RlVVyhvMaWSBTOvXNeiW3e5FwdS5ePW0LGEu17zT139ktg==} esbuild-register@3.6.0: resolution: {integrity: sha512-H2/S7Pm8a9CL1uhp9OvjwrBh5Pvx0H8qVOxNu8Wed9Y7qv56MPtq+GGM8RJpq6glYJn9Wspr8uw7l55uyinNeg==} @@ -671,15 +623,8 @@ packages: engines: {node: '>=18'} hasBin: true - escape-html@1.0.3: - resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} - - etag@1.8.1: - resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} - engines: {node: '>= 0.6'} - - eventemitter3@5.0.1: - resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} expand-template@2.0.3: resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==} @@ -700,10 +645,6 @@ packages: resolution: {integrity: sha512-SKmowqGTJoPzLO1T0BBJpkfp3EMacCMOuH40hOUbrbzElVktk4DioXVM99QkLCyKoiuOmyjgcWMpVz2xjE7LZw==} engines: {node: '>=0.10.0'} - fresh@2.0.0: - resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} - engines: {node: '>= 0.8'} - fs-constants@1.0.0: resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==} @@ -732,9 +673,9 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - http-errors@2.0.1: - resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} - engines: {node: '>= 0.8'} + hono@4.11.4: + resolution: {integrity: sha512-U7tt8JsyrxSRKspfhtLET79pU8K+tInj5QZXs1jSugO1Vq5dFj3kmZsRldo29mTBfcjDRVRXrEZ6LS63Cog9ZA==} + engines: {node: '>=16.9.0'} ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} @@ -794,14 +735,6 @@ packages: resolution: {integrity: sha512-qtmzAS6t6grwEkNrunqTBdn0qKwFgNWvlxUbAV8es9M7Ot1EbyApytCnvE0jALPa46ZpKDUo527kKiaWplmlFA==} engines: {node: '>=0.10.0'} - mime-db@1.54.0: - resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} - engines: {node: '>= 0.6'} - - mime-types@3.0.2: - resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} - engines: {node: '>=18'} - mimic-response@3.1.0: resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} engines: {node: '>=10'} @@ -834,10 +767,6 @@ packages: resolution: {integrity: sha512-zsFhmbkAzwhTft6nd3VxcG0cvJsT70rL+BIGHWVq5fi6MwGrHwzqKaxXE+Hl2GmnGItnDKPPkO5/LQqjVkIdFg==} engines: {node: '>=10'} - on-finished@2.4.1: - resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} - engines: {node: '>= 0.8'} - once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -845,13 +774,6 @@ packages: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} engines: {node: '>=0.10.0'} - path-to-regexp@8.3.0: - resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} - - pkijs@3.3.3: - resolution: {integrity: sha512-+KD8hJtqQMYoTuL1bbGOqxb4z+nZkTAwVdNtWwe8Tc2xNbEmdJYIYoc6Qt0uF55e6YW6KuTHw1DjQ18gMhzepw==} - engines: {node: '>=16.0.0'} - playwright-core@1.57.0: resolution: {integrity: sha512-agTcKlMw/mjBWOnD6kFZttAAGHgi/Nw0CZ2o6JqWSbMlI219lAFLZZCyqByTsvVAJq5XA5H8cA6PrvBRpBWEuQ==} engines: {node: '>=18'} @@ -933,17 +855,6 @@ packages: puppeteer-extra: optional: true - pvtsutils@1.3.6: - resolution: {integrity: sha512-PLgQXQ6H2FWCaeRak8vvk1GW462lMxB5s3Jm673N82zI4vqtVUPuZdffdZbPDFRoU8kAhItWFtPCWiPpp4/EDg==} - - pvutils@1.1.5: - resolution: {integrity: sha512-KTqnxsgGiQ6ZAzZCVlJH5eOjSnvlyEgx1m8bkRJfOhmGRqfo5KLvmAlACQkrjEtOQ4B7wF9TdSLIs9O90MX9xA==} - engines: {node: '>=16.0.0'} - - range-parser@1.2.1: - resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} - engines: {node: '>= 0.6'} - rc@1.2.8: resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==} hasBin: true @@ -952,9 +863,6 @@ packages: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} - reflect-metadata@0.2.2: - resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - resolve-pkg-maps@1.0.0: resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} @@ -966,22 +874,11 @@ packages: safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - selfsigned@5.4.0: - resolution: {integrity: sha512-Yn8qZOOJv+NhcGY19iC+ngW6hlUCNpvWEkrKllXNhmkLgR9fcErm8EqZ/wev7/tiwjKC9qj17Fa/PtBNzb6q8g==} - engines: {node: '>=15.6.0'} - semver@7.7.3: resolution: {integrity: sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==} engines: {node: '>=10'} hasBin: true - send@1.2.1: - resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} - engines: {node: '>= 18'} - - setprototypeof@1.2.0: - resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} - shallow-clone@0.1.2: resolution: {integrity: sha512-J1zdXCky5GmNnuauESROVu31MQSnLoYvlyEn6j2Ztk6Q5EHFIhxkMhYcv6vuDzl2XEzoRr856QwzMgWM/TmZgw==} engines: {node: '>=0.10.0'} @@ -999,10 +896,6 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} @@ -1017,20 +910,6 @@ packages: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} engines: {node: '>=6'} - toidentifier@1.0.1: - resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} - engines: {node: '>=0.6'} - - tslib@1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - - tslib@2.8.1: - resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} - - tsyringe@4.10.0: - resolution: {integrity: sha512-axr3IdNuVIxnaK5XGEUFTu3YmAQ6lllgrvqfEoR16g/HGnYY/6We4oWENtAnzK6/LpJ2ur9PAb80RBt7/U4ugw==} - engines: {node: '>= 6.0.0'} - tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -1055,8 +934,8 @@ packages: peerDependencies: zod: ^3.25 || ^4 - zod@4.2.1: - resolution: {integrity: sha512-0wZ1IRqGGhMP76gLqz8EyfBXKk0J2qo2+H3fi4mcUP/KtTocoX08nmIAHl1Z2kJIZbZee8KOpBCSNPRgauucjw==} + zod@4.3.5: + resolution: {integrity: sha512-k7Nwx6vuWx1IJ9Bjuf4Zt1PEllcwe7cls3VNzm4CQ1/hgtFUK2bRNG3rvnpPUhFjmqJKAKtjV576KnUkHocg/g==} snapshots: @@ -1216,133 +1095,34 @@ snapshots: '@esbuild/win32-x64@0.25.12': optional: true - '@kevisual/code-builder@0.0.2(dotenv@17.2.3)': - dependencies: - '@kevisual/use-config': 1.0.21(dotenv@17.2.3) - nanoid: 5.1.6 - transitivePeerDependencies: - - dotenv + '@kevisual/code-builder@0.0.3': {} '@kevisual/context@0.0.4': {} + '@kevisual/js-filter@0.0.5': {} + '@kevisual/load@0.0.6': dependencies: - eventemitter3: 5.0.1 + eventemitter3: 5.0.4 - '@kevisual/router@0.0.49': + '@kevisual/router@0.0.59': dependencies: - path-to-regexp: 8.3.0 - selfsigned: 5.4.0 - send: 1.2.1 - transitivePeerDependencies: - - supports-color + hono: 4.11.4 - '@kevisual/types@0.0.10': {} + '@kevisual/types@0.0.11': {} - '@kevisual/use-config@1.0.21(dotenv@17.2.3)': + '@kevisual/use-config@1.0.28(dotenv@17.2.3)': dependencies: '@kevisual/load': 0.0.6 dotenv: 17.2.3 - '@noble/hashes@1.4.0': {} - - '@peculiar/asn1-cms@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - '@peculiar/asn1-x509-attr': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-csr@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-ecc@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pfx@2.6.0': - dependencies: - '@peculiar/asn1-cms': 2.6.0 - '@peculiar/asn1-pkcs8': 2.6.0 - '@peculiar/asn1-rsa': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pkcs8@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-pkcs9@2.6.0': - dependencies: - '@peculiar/asn1-cms': 2.6.0 - '@peculiar/asn1-pfx': 2.6.0 - '@peculiar/asn1-pkcs8': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - '@peculiar/asn1-x509-attr': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-rsa@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-schema@2.6.0': - dependencies: - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/asn1-x509-attr@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - asn1js: 3.0.7 - tslib: 2.8.1 - - '@peculiar/asn1-x509@2.6.0': - dependencies: - '@peculiar/asn1-schema': 2.6.0 - asn1js: 3.0.7 - pvtsutils: 1.3.6 - tslib: 2.8.1 - - '@peculiar/x509@1.14.2': - dependencies: - '@peculiar/asn1-cms': 2.6.0 - '@peculiar/asn1-csr': 2.6.0 - '@peculiar/asn1-ecc': 2.6.0 - '@peculiar/asn1-pkcs9': 2.6.0 - '@peculiar/asn1-rsa': 2.6.0 - '@peculiar/asn1-schema': 2.6.0 - '@peculiar/asn1-x509': 2.6.0 - pvtsutils: 1.3.6 - reflect-metadata: 0.2.2 - tslib: 2.8.1 - tsyringe: 4.10.0 - '@types/better-sqlite3@7.6.13': dependencies: - '@types/node': 25.0.3 + '@types/node': 25.0.9 - '@types/bun@1.3.5': + '@types/bun@1.3.6': dependencies: - bun-types: 1.3.5 + bun-types: 1.3.6 '@types/debug@4.1.12': dependencies: @@ -1350,7 +1130,7 @@ snapshots: '@types/ms@2.1.0': {} - '@types/node@25.0.3': + '@types/node@25.0.9': dependencies: undici-types: 7.16.0 @@ -1358,17 +1138,11 @@ snapshots: arr-union@3.1.0: {} - asn1js@3.0.7: - dependencies: - pvtsutils: 1.3.6 - pvutils: 1.1.5 - tslib: 2.8.1 - balanced-match@1.0.2: {} base64-js@1.5.1: {} - better-sqlite3@12.5.0: + better-sqlite3@12.6.2: dependencies: bindings: 1.5.0 prebuild-install: 7.1.3 @@ -1395,11 +1169,9 @@ snapshots: base64-js: 1.5.1 ieee754: 1.2.1 - bun-types@1.3.5: + bun-types@1.3.6: dependencies: - '@types/node': 25.0.3 - - bytestreamjs@2.0.1: {} + '@types/node': 25.0.9 chownr@1.1.4: {} @@ -1427,8 +1199,6 @@ snapshots: deepmerge@4.3.1: {} - depd@2.0.0: {} - detect-libc@2.1.2: {} dotenv@17.2.3: {} @@ -1442,21 +1212,17 @@ snapshots: transitivePeerDependencies: - supports-color - drizzle-orm@0.45.1(@types/better-sqlite3@7.6.13)(better-sqlite3@12.5.0)(bun-types@1.3.5): + drizzle-orm@0.45.1(@types/better-sqlite3@7.6.13)(better-sqlite3@12.6.2)(bun-types@1.3.6): optionalDependencies: '@types/better-sqlite3': 7.6.13 - better-sqlite3: 12.5.0 - bun-types: 1.3.5 - - ee-first@1.1.1: {} - - encodeurl@2.0.0: {} + better-sqlite3: 12.6.2 + bun-types: 1.3.6 end-of-stream@1.4.5: dependencies: once: 1.4.0 - es-toolkit@1.43.0: {} + es-toolkit@1.44.0: {} esbuild-register@3.6.0(esbuild@0.25.12): dependencies: @@ -1519,11 +1285,7 @@ snapshots: '@esbuild/win32-ia32': 0.25.12 '@esbuild/win32-x64': 0.25.12 - escape-html@1.0.3: {} - - etag@1.8.1: {} - - eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} expand-template@2.0.3: {} @@ -1537,8 +1299,6 @@ snapshots: dependencies: for-in: 1.0.2 - fresh@2.0.0: {} - fs-constants@1.0.0: {} fs-extra@10.1.0: @@ -1569,13 +1329,7 @@ snapshots: graceful-fs@4.2.11: {} - http-errors@2.0.1: - dependencies: - depd: 2.0.0 - inherits: 2.0.4 - setprototypeof: 1.2.0 - statuses: 2.0.2 - toidentifier: 1.0.1 + hono@4.11.4: {} ieee754@1.2.1: {} @@ -1626,12 +1380,6 @@ snapshots: clone-deep: 0.2.4 kind-of: 3.2.2 - mime-db@1.54.0: {} - - mime-types@3.0.2: - dependencies: - mime-db: 1.54.0 - mimic-response@3.1.0: {} minimatch@3.1.2: @@ -1657,27 +1405,12 @@ snapshots: dependencies: semver: 7.7.3 - on-finished@2.4.1: - dependencies: - ee-first: 1.1.1 - once@1.4.0: dependencies: wrappy: 1.0.2 path-is-absolute@1.0.1: {} - path-to-regexp@8.3.0: {} - - pkijs@3.3.3: - dependencies: - '@noble/hashes': 1.4.0 - asn1js: 3.0.7 - bytestreamjs: 2.0.1 - pvtsutils: 1.3.6 - pvutils: 1.1.5 - tslib: 2.8.1 - playwright-core@1.57.0: {} playwright-extra-plugin-stealth@0.0.1: {} @@ -1759,14 +1492,6 @@ snapshots: transitivePeerDependencies: - supports-color - pvtsutils@1.3.6: - dependencies: - tslib: 2.8.1 - - pvutils@1.1.5: {} - - range-parser@1.2.1: {} - rc@1.2.8: dependencies: deep-extend: 0.6.0 @@ -1780,8 +1505,6 @@ snapshots: string_decoder: 1.3.0 util-deprecate: 1.0.2 - reflect-metadata@0.2.2: {} - resolve-pkg-maps@1.0.0: {} rimraf@3.0.2: @@ -1790,31 +1513,8 @@ snapshots: safe-buffer@5.2.1: {} - selfsigned@5.4.0: - dependencies: - '@peculiar/x509': 1.14.2 - pkijs: 3.3.3 - semver@7.7.3: {} - send@1.2.1: - dependencies: - debug: 4.4.3 - encodeurl: 2.0.0 - escape-html: 1.0.3 - etag: 1.8.1 - fresh: 2.0.0 - http-errors: 2.0.1 - mime-types: 3.0.2 - ms: 2.1.3 - on-finished: 2.4.1 - range-parser: 1.2.1 - statuses: 2.0.2 - transitivePeerDependencies: - - supports-color - - setprototypeof@1.2.0: {} - shallow-clone@0.1.2: dependencies: is-extendable: 0.1.1 @@ -1837,8 +1537,6 @@ snapshots: source-map@0.6.1: {} - statuses@2.0.2: {} - string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 @@ -1860,16 +1558,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - toidentifier@1.0.1: {} - - tslib@1.14.1: {} - - tslib@2.8.1: {} - - tsyringe@4.10.0: - dependencies: - tslib: 1.14.1 - tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -1886,8 +1574,8 @@ snapshots: wrappy@1.0.2: {} - zod-to-json-schema@3.25.1(zod@4.2.1): + zod-to-json-schema@3.25.1(zod@4.3.5): dependencies: - zod: 4.2.1 + zod: 4.3.5 - zod@4.2.1: {} + zod@4.3.5: {} diff --git a/src/app.ts b/src/app.ts index 4a77484..ae2895f 100644 --- a/src/app.ts +++ b/src/app.ts @@ -1,5 +1,5 @@ import { App } from '@kevisual/router' -import { useConfigKey } from '@kevisual/context' +import { useContextKey } from '@kevisual/context' import { useConfig } from '@kevisual/use-config' import Database from 'better-sqlite3'; import { drizzle } from 'drizzle-orm/better-sqlite3'; @@ -8,7 +8,7 @@ import * as schema from './db/schema.ts'; export { schema } export const config = useConfig() -export const app = useConfigKey('app', () => new App({ +export const app = useContextKey('app', () => new App({ serverOptions: { cors: { origin: '*', @@ -27,14 +27,14 @@ app.route({ } }).addTo(app); -export const db = useConfigKey('db', () => { +export const db = useContextKey('db', () => { const sqlite = new Database(config.DATABASE_URL || 'storage/browser-helper/data.sqlite3'); sqlite.pragma('journal_mode = WAL'); const db = drizzle({ client: sqlite, schema }); return db; }) -export const core = useConfigKey('core', () => new Core({ +export const core = useContextKey('core', () => new Core({ useDebugPort: true, // 不使用debugPort,避免被网站检测 useCDPConnect: true, // 使用纯Playwright模式而不是CDP连接 listeners: [ diff --git a/src/index.ts b/src/index.ts index c09f56a..9e2dbfb 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,7 +3,7 @@ export { app, db } from './app.ts'; export { Core } from './playwright/core.ts'; import './routes/index.ts'; // 如果是直接运行,则启动应用 - +import { createRouterAgentPluginFn } from '@kevisual/router/src/opencode.ts' app.route({ id: 'auth', description: 'Token 权限验证,临时方案', @@ -18,4 +18,9 @@ if (import.meta.main || isPm2) { app.listen(52000, () => { console.log('Application is running on http://localhost:52000'); }) -} \ No newline at end of file +} + +export const browserAgentPlugin = createRouterAgentPluginFn({ + // router: app., + router: app, +}) \ No newline at end of file diff --git a/src/routes/good/index.ts b/src/routes/good/index.ts index cb888ad..f302f5f 100644 --- a/src/routes/good/index.ts +++ b/src/routes/good/index.ts @@ -93,4 +93,28 @@ app.route({ } }, ctx) ctx.forward(res) +}).addTo(app); + +// 调用 path: good key: searchTemplate +app.route({ + path: 'good', + key: 'searchTemplate', + description: '搜索小红书的模板相关,参数是keyword,默认搜索"网站模板"', + middleware: ['auth'], + metadata: { + tags: ['小红书', '网站模板'], + } +}).define(async (ctx) => { + const { keyword = '网站模板', ...rest } = ctx.query; + const res = await app.run({ + path: 'xhs', + key: 'search-notes', + payload: { + keyword: keyword, + scrollTimes: 10, + ...rest, + token: ctx.query?.token as string, + } + }, ctx) + ctx.forward(res) }).addTo(app); \ No newline at end of file diff --git a/src/routes/xhs/search-notes.ts b/src/routes/xhs/search-notes.ts index eb22bfb..ab254c7 100644 --- a/src/routes/xhs/search-notes.ts +++ b/src/routes/xhs/search-notes.ts @@ -236,7 +236,7 @@ app.route({ } }) const userIds = notes.map(note => note.id).filter(id => id); - const userList = await db.select().from(xhsUser).where(sql`id IN (${userIds.join(',')})`); + const userList = userIds.length > 0 ? await db.select().from(xhsUser).where(sql`id IN (${userIds.join(',')})`) : []; // 如果用户表有bun的tags,对关键字进行屏蔽,对应的笔记默认打上禁止标签 for (const note of notes) { const user = userList.find(u => u.id === note.user_id); @@ -247,6 +247,11 @@ app.route({ } } } + if (notes.length === 0) { + console.log('没有笔记需要保存'); + ctx.body = { success: true, message: '没有笔记需要保存' }; + return; + } await db.insert(xhsNote).values(notes).onConflictDoUpdate({ target: xhsNote.id, set: { @@ -264,14 +269,16 @@ app.route({ console.log(`已保存 ${data.length} 条搜索笔记结果`); // 保存用户信息,去重 const uniqueUsers = Array.from(new Map(notesUser.filter(u => u !== null).map(u => [u!.id, u!])).values()); - await db.insert(xhsUser).values(uniqueUsers).onConflictDoUpdate({ - target: xhsUser.id, - set: { - nickname: sql`excluded.nickname`, - avatar: sql`excluded.avatar`, - }, - }).execute(); - console.log(`已保存 ${uniqueUsers.length} 条用户信息`); + if (uniqueUsers.length > 0) { + await db.insert(xhsUser).values(uniqueUsers).onConflictDoUpdate({ + target: xhsUser.id, + set: { + nickname: sql`excluded.nickname`, + avatar: sql`excluded.avatar`, + }, + }).execute(); + console.log(`已保存 ${uniqueUsers.length} 条用户信息`); + } // 检查 keyword 是否存在于 xhsTags 的 title 中,如果不存在则添加 if (keyword) { diff --git a/src/test/xhs/index.ts b/src/test/xhs/index.ts index bc61230..d18d079 100644 --- a/src/test/xhs/index.ts +++ b/src/test/xhs/index.ts @@ -16,3 +16,18 @@ program console.log(showMore(res)); }); + + +program.command('xhs:search-template') + .description('搜索小红书的模板相关,参数是keyword,默认搜索"网站模板"') + .option('-k, --keyword ', '搜索关键词', '网站模板') + .action(async (options) => { + const res = await app.run({ + path: 'good', + key: 'searchTemplate', + payload: { + keyword: options.keyword, + } + }); + console.log(showMore(res)); + }); \ No newline at end of file