From 2c800d336c8701328681db480176310ca5d58907 Mon Sep 17 00:00:00 2001 From: abearixong Date: Sun, 16 Nov 2025 13:32:35 +0800 Subject: [PATCH] update --- .gitignore | 5 +- agent/corn.ts | 11 ++ agent/ddns/get-ip.ts | 8 ++ agent/index.ts | 10 +- agent/ip.ts | 9 +- agent/routes/cloudflare.ts | 26 +++++ agent/task.ts | 92 ++++++++++++++++ html/index.html | 1 + package.json | 27 ++++- pnpm-lock.yaml | 209 +++++++++++++++++++++++++++++++++++++ tsconfig.json | 34 ++++++ 11 files changed, 414 insertions(+), 18 deletions(-) create mode 100644 agent/corn.ts create mode 100644 agent/ddns/get-ip.ts create mode 100644 agent/routes/cloudflare.ts create mode 100644 agent/task.ts create mode 100644 html/index.html create mode 100644 tsconfig.json diff --git a/.gitignore b/.gitignore index b1a3dfa..f5beccd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules .DS_Store dist +pack-dist *.local .vite-inspect .remote-assets @@ -10,4 +11,6 @@ components.d.ts .env -!.env*example \ No newline at end of file +!.env*example + +storage \ No newline at end of file diff --git a/agent/corn.ts b/agent/corn.ts new file mode 100644 index 0000000..cf47783 --- /dev/null +++ b/agent/corn.ts @@ -0,0 +1,11 @@ +import cron from 'node-cron'; +import './index.ts' +import { main } from './task.ts'; + +// 每2个小时执行一次更新任务 +cron.schedule('0 */2 * * *', async () => { + main() +}); + +// first run +main() diff --git a/agent/ddns/get-ip.ts b/agent/ddns/get-ip.ts new file mode 100644 index 0000000..7989a03 --- /dev/null +++ b/agent/ddns/get-ip.ts @@ -0,0 +1,8 @@ +const baseURLv4 = 'https://4.ipw.cn/'; +const baseURLv6 = 'https://6.ipw.cn/'; +export const getPublicIp = async (type: 'v4' | 'v6'): Promise => { + const url = type === 'v4' ? baseURLv4 : baseURLv6; + const response = await fetch(url); + const ip = (await response.text()).trim(); + return ip; +} \ No newline at end of file diff --git a/agent/index.ts b/agent/index.ts index 719ec59..0d77e42 100644 --- a/agent/index.ts +++ b/agent/index.ts @@ -1,14 +1,8 @@ import {app} from './app.ts'; import './ip' - +import './task.ts'; +import './routes/cloudflare.ts'; // app.listen(8080); -app.call({ - path: 'ip', - key: 'v6' -}).then(res => { - console.log('IPv4 Address:', res); -}) - export { app }; \ No newline at end of file diff --git a/agent/ip.ts b/agent/ip.ts index 7266283..a033d3d 100644 --- a/agent/ip.ts +++ b/agent/ip.ts @@ -1,10 +1,8 @@ const baseURLv4 = 'https://4.ipw.cn/'; const baseURLv6 = 'https://6.ipw.cn/'; - import { app } from './app.ts'; - app.route({ path: 'ip', key: 'v4', @@ -12,7 +10,7 @@ app.route({ }).define(async (ctx) => { const response = await fetch(baseURLv4); const ip = (await response.text()).trim(); - if(!isIpv4(ip)) { + if (!isIpv4(ip)) { ctx.throw?.('获取地址失败'); } ctx.body = { ip }; @@ -25,7 +23,7 @@ app.route({ }).define(async (ctx) => { const response = await fetch(baseURLv6); const ip = (await response.text()).trim(); - if(!isIpv6(ip)) { + if (!isIpv6(ip)) { ctx.throw?.('获取地址失败'); } ctx.body = { ip }; @@ -38,4 +36,5 @@ export const isIpv6 = (ip: string): boolean => { export const isIpv4 = (ip: string): boolean => { return ip.split('.').length === 4; -} \ No newline at end of file +} + diff --git a/agent/routes/cloudflare.ts b/agent/routes/cloudflare.ts new file mode 100644 index 0000000..c1b8238 --- /dev/null +++ b/agent/routes/cloudflare.ts @@ -0,0 +1,26 @@ +import {app} from '../app.ts'; +import { CloudflareDDNS } from '../ddns/cloudflare/index.ts'; + +app.route({ + path: 'cf', + key: 'update', + description: '更新Cloudflare DNS记录, 需要提供zone_id, record_id, domain, new_ip, api_token, type参数, type参数可选,默认为A记录, A 或AAAA', +}).define(async (ctx) => { + const { zone_id, record_id, domain, new_ip, api_token, type = 'A' } = ctx.query || {}; + + if(!zone_id || !record_id || !domain || !new_ip || !api_token) { + ctx.throw?.('缺少必要参数'); + } + + const cf = new CloudflareDDNS(); + const result = await cf.updateRecord({ + zone_id, + record_id, + domain, + new_ip, + api_token, + type, + }); + + ctx.body = { result }; +}).addTo(app); \ No newline at end of file diff --git a/agent/task.ts b/agent/task.ts new file mode 100644 index 0000000..2c13033 --- /dev/null +++ b/agent/task.ts @@ -0,0 +1,92 @@ +import { app } from './app.ts'; +import { createStorage } from "unstorage"; +import fsDriver from "unstorage/drivers/fs"; + +const storage = createStorage({ + driver: fsDriver({ + base: process.cwd() + '/storage/ddns-agent' + }), +}); + +type CloudflareConfig = { + // Cloudflare 访问地址 + website: string; + domain: string; + zone_id: string; + // 更新IPv4记录的ID + record_id4: string; + // 更新IPv6记录的ID + record_id6: string; + api_token: string; + ipv6: string; + ipv4: string; + flag: number; // 0: 不更新, 1: 仅IPv4, 2: 仅IPv6, 3: IPv4和IPv6 + time: string; // 上次更新时间戳 +} +app.route({ + path: 'ip', + key: 'task', + description: `执行IP更新任务 +1. 读取配置文件cloudflare.json +2. 根据flag决定更新IPv4和/或IPv6地址 +3. 获取当前公网IP地址 +4. 如果IP地址有变化则调用 router: cf/update 更新DNS记录 +5. 保存最新的IP地址和更新时间戳到配置文件 +`, +}).define(async (ctx) => { + const config = await storage.getItem('cloudflare.json'); + if (!config) { + ctx.throw?.('未找到配置'); + } + const now = Date.now(); + const date = new Date(now); + const updateIp = async (isV4 = true) => { + const res = await app.call({ path: 'ip', key: isV4 ? 'v4' : 'v6' }); + if (res.code !== 200) { + ctx.throw(res.message); + } + const newIp = res.body.ip as string; + const oldIp = isV4 ? config.ipv4 : config.ipv6; + if (newIp !== oldIp) { + // IP地址有变化,更新DNS记录 + await app.call({ path: 'cf', key: 'update' }, { + zone_id: config.zone_id, + record_id: isV4 ? config.record_id4 : config.record_id6, + domain: config.domain, + new_ip: newIp, + api_token: config.api_token, + type: isV4 ? 'A' : 'AAAA', + }); + // 更新配置文件中的IP地址 + if (isV4) { + config.ipv4 = newIp; + } else { + config.ipv6 = newIp; + } + config.time = date.toLocaleString(); + await storage.setItem('cloudflare.json', config); + console.log(date.toLocaleString() + ` 更新 ${isV4 ? 'IPv4' : 'IPv6'} 地址为: ${newIp}`); + } else { + console.log(date.toLocaleString() + ` ${isV4 ? 'IPv4' : 'IPv6'} 地址未改变: ${newIp}`); + } + } + if (config.flag === 1) { + await updateIp(true); + } + if (config.flag === 2) { + await updateIp(false); + } + if (config.flag === 3) { + await updateIp(true); + await updateIp(false); + } + ctx.body = { message: '任务完成' }; +}).addTo(app); + +export const main = () => { + app.call({ + path: 'ip', + key: 'task', + }) +} + diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..a8a9406 --- /dev/null +++ b/html/index.html @@ -0,0 +1 @@ +this is a test \ No newline at end of file diff --git a/package.json b/package.json index 3b10c5e..4100da4 100644 --- a/package.json +++ b/package.json @@ -3,18 +3,37 @@ "version": "1.0.0", "description": "", "main": "index.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "type": "module", + "basename": "/root/ddns-agent", + "app": { + "entry": "agent/index.ts", + "type": "script", + "runtime": [ + "cli" + ] }, + "scripts": { + "pub": "ev deploy . -k ddns-agent -v 1.0.0 -u", + "packup": "ev pack -p", + "pm2": "pm2 start agent/corn.ts --interpreter bun --name ddns-agent" + }, + "files": [ + "agent", + "html", + "tsconfig.json" + ], "keywords": [], "author": "", "license": "ISC", "packageManager": "pnpm@10.19.0", "dependencies": { "@kevisual/router": "^0.0.30", - "crypto-js": "^4.2.0" + "crypto-js": "^4.2.0", + "node-cron": "^4.2.1", + "unstorage": "^1.17.2" }, "devDependencies": { + "@kevisual/types": "^0.0.10", "@types/node": "^24.10.1" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0cf9d38..a7b2057 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,7 +14,16 @@ importers: crypto-js: specifier: ^4.2.0 version: 4.2.0 + node-cron: + specifier: ^4.2.1 + version: 4.2.1 + unstorage: + specifier: ^1.17.2 + version: 1.17.2 devDependencies: + '@kevisual/types': + specifier: ^0.0.10 + version: 0.0.10 '@types/node': specifier: ^24.10.1 version: 24.10.1 @@ -24,9 +33,26 @@ packages: '@kevisual/router@0.0.30': resolution: {integrity: sha512-/mBo7aZFWjT4QfHkI5HPXfdgSwZzt3mAVei7dcNSBTPe9KQSoYKZ8BTq9VTUj3XE0sI6o1bZjlLYvinpVnZilw==} + '@kevisual/types@0.0.10': + resolution: {integrity: sha512-Q73uzzjk9UidumnmCvOpgzqDDvQxsblz22bIFuoiioUFJWwaparx8bpd8ArRyFojicYL1YJoFDzDZ9j9NN8grA==} + '@types/node@24.10.1': resolution: {integrity: sha512-GNWcUTRBgIRJD5zj+Tq0fKOJ5XZajIiBroOF0yvj2bSU1WvNdYS/dn9UxwsujGW4JX06dnHyjV2y9rRaybH0iQ==} + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + cookie-es@1.2.2: + resolution: {integrity: sha512-+W7VmiVINB+ywl1HGXJXmrqkOhpKrIiVZV6tQuV54ZyQC7MMuBt81Vc336GMLoHBq5hV/F9eXgt5Mnx0Rha5Fg==} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} @@ -39,10 +65,16 @@ packages: supports-color: optional: true + defu@6.1.4: + resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + depd@2.0.0: resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} engines: {node: '>= 0.8'} + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -61,6 +93,9 @@ packages: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + h3@1.15.4: + resolution: {integrity: sha512-z5cFQWDffyOe4vQ9xIqNfCZdV4p//vy6fBnr8Q1AWnVZ0teurKMG66rLj++TKwKPUP3u7iMUvrvKaEUiQw2QWQ==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -68,6 +103,12 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + lru-cache@10.4.3: + resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + mime-db@1.54.0: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} @@ -79,10 +120,27 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + node-cron@4.2.1: + resolution: {integrity: sha512-lgimEHPE/QDgFlywTd8yTR61ptugX3Qer29efeyWw2rv259HtGBNn1vZVmp8lB9uo9wC0t/AT4iGqXxia+CJFg==} + engines: {node: '>=6.0.0'} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + node-forge@1.3.1: resolution: {integrity: sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==} engines: {node: '>= 6.13.0'} + node-mock-http@1.0.3: + resolution: {integrity: sha512-jN8dK25fsfnMrVsEhluUTPkBFY+6ybu7jSB1n+ri/vOGjJxU8J9CZhpSGkHXSkFjtUhbmoncG/YG9ta5Ludqog==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} @@ -90,10 +148,21 @@ packages: path-to-regexp@8.3.0: resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + picomatch@2.3.1: + resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} + engines: {node: '>=8.6'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + selfsigned@3.0.1: resolution: {integrity: sha512-6U6w6kSLrM9Zxo0D7mC7QdGS6ZZytMWBnj/vhF9p+dAHx6CwGezuRcO4VclTbrrI7mg7SD6zNiqXUuBHOVopNQ==} engines: {node: '>=10'} @@ -117,9 +186,77 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + ufo@1.6.1: + resolution: {integrity: sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + unstorage@1.17.2: + resolution: {integrity: sha512-cKEsD6iBWJgOMJ6vW1ID/SYuqNf8oN4yqRk8OYqaVQ3nnkJXOT1PSpaMh2QfzLs78UN5kSNRD2c/mgjT8tX7+w==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6.0.3 || ^7.0.0 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1.0.1 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + snapshots: '@kevisual/router@0.0.30': @@ -130,18 +267,39 @@ snapshots: transitivePeerDependencies: - supports-color + '@kevisual/types@0.0.10': {} + '@types/node@24.10.1': dependencies: undici-types: 7.16.0 + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.1 + + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + cookie-es@1.2.2: {} + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + crypto-js@4.2.0: {} debug@4.4.3: dependencies: ms: 2.1.3 + defu@6.1.4: {} + depd@2.0.0: {} + destr@2.0.5: {} + ee-first@1.1.1: {} encodeurl@2.0.0: {} @@ -152,6 +310,18 @@ snapshots: fresh@2.0.0: {} + h3@1.15.4: + dependencies: + cookie-es: 1.2.2 + crossws: 0.3.5 + defu: 6.1.4 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.3 + radix3: 1.1.2 + ufo: 1.6.1 + uncrypto: 0.1.3 + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -162,6 +332,10 @@ snapshots: inherits@2.0.4: {} + iron-webcrypto@1.2.1: {} + + lru-cache@10.4.3: {} + mime-db@1.54.0: {} mime-types@3.0.1: @@ -170,16 +344,36 @@ snapshots: ms@2.1.3: {} + node-cron@4.2.1: {} + + node-fetch-native@1.6.7: {} + node-forge@1.3.1: {} + node-mock-http@1.0.3: {} + + normalize-path@3.0.0: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.1 + on-finished@2.4.1: dependencies: ee-first: 1.1.1 path-to-regexp@8.3.0: {} + picomatch@2.3.1: {} + + radix3@1.1.2: {} + range-parser@1.2.1: {} + readdirp@4.1.2: {} + selfsigned@3.0.1: dependencies: node-forge: 1.3.1 @@ -208,4 +402,19 @@ snapshots: toidentifier@1.0.1: {} + ufo@1.6.1: {} + + uncrypto@0.1.3: {} + undici-types@7.16.0: {} + + unstorage@1.17.2: + dependencies: + anymatch: 3.1.3 + chokidar: 4.0.3 + destr: 2.0.5 + h3: 1.15.4 + lru-cache: 10.4.3 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.1 diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..1e979bb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,34 @@ +{ + "compilerOptions": { + "module": "NodeNext", + "target": "esnext", + "noImplicitAny": false, + "outDir": "./dist", + "sourceMap": false, + "allowJs": true, + "newLine": "LF", + "baseUrl": "./", + "typeRoots": [ + "node_modules/@types", + ], + "declaration": false, + "noEmit": true, + "allowImportingTsExtensions": true, + "moduleResolution": "NodeNext", + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "paths": { + "@/*": [ + "src/*" + ], + "@agent/*": [ + "agent/*" + ], + } + }, + "include": [ + "src/**/*.ts", + "agent/**/*.ts", + ] +} \ No newline at end of file