feat: 完成 ApiState Temporal native 开发链
This commit is contained in:
@@ -15,6 +15,7 @@
|
|||||||
"@types/bun": "^1.2.21",
|
"@types/bun": "^1.2.21",
|
||||||
"@types/luxon": "^3.7.1",
|
"@types/luxon": "^3.7.1",
|
||||||
"typescript": "^5.9.2",
|
"typescript": "^5.9.2",
|
||||||
|
"vite": "^8.1.5",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -23,6 +24,12 @@
|
|||||||
"protobufjs",
|
"protobufjs",
|
||||||
],
|
],
|
||||||
"packages": {
|
"packages": {
|
||||||
|
"@emnapi/core": ["@emnapi/core@1.11.1", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" } }, "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ=="],
|
||||||
|
|
||||||
|
"@emnapi/runtime": ["@emnapi/runtime@1.11.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw=="],
|
||||||
|
|
||||||
|
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
|
||||||
|
|
||||||
"@grpc/grpc-js": ["@grpc/grpc-js@1.14.4", "", { "dependencies": { "@grpc/proto-loader": "^0.8.0", "@js-sdsl/ordered-map": "^4.4.2" } }, "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ=="],
|
"@grpc/grpc-js": ["@grpc/grpc-js@1.14.4", "", { "dependencies": { "@grpc/proto-loader": "^0.8.0", "@js-sdsl/ordered-map": "^4.4.2" } }, "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ=="],
|
||||||
|
|
||||||
"@grpc/proto-loader": ["@grpc/proto-loader@0.8.1", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.5.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg=="],
|
"@grpc/proto-loader": ["@grpc/proto-loader@0.8.1", "", { "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", "protobufjs": "^7.5.5", "yargs": "^17.7.2" }, "bin": { "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" } }, "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg=="],
|
||||||
@@ -67,6 +74,10 @@
|
|||||||
|
|
||||||
"@jsonjoy.com/util": ["@jsonjoy.com/util@1.9.0", "", { "dependencies": { "@jsonjoy.com/buffers": "^1.0.0", "@jsonjoy.com/codegen": "^1.0.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ=="],
|
"@jsonjoy.com/util": ["@jsonjoy.com/util@1.9.0", "", { "dependencies": { "@jsonjoy.com/buffers": "^1.0.0", "@jsonjoy.com/codegen": "^1.0.0" }, "peerDependencies": { "tslib": "2" } }, "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ=="],
|
||||||
|
|
||||||
|
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.6", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg=="],
|
||||||
|
|
||||||
|
"@oxc-project/types": ["@oxc-project/types@0.139.0", "", {}, "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw=="],
|
||||||
|
|
||||||
"@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
|
"@protobufjs/aspromise": ["@protobufjs/aspromise@1.1.2", "", {}, "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ=="],
|
||||||
|
|
||||||
"@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
|
"@protobufjs/base64": ["@protobufjs/base64@1.1.2", "", {}, "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg=="],
|
||||||
@@ -85,6 +96,38 @@
|
|||||||
|
|
||||||
"@protobufjs/utf8": ["@protobufjs/utf8@1.1.2", "", {}, "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug=="],
|
"@protobufjs/utf8": ["@protobufjs/utf8@1.1.2", "", {}, "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.1.5", "", { "os": "android", "cpu": "arm64" }, "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.1.5", "", { "os": "darwin", "cpu": "arm64" }, "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.1.5", "", { "os": "darwin", "cpu": "x64" }, "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.1.5", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.1.5", "", { "os": "linux", "cpu": "arm" }, "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.1.5", "", { "os": "linux", "cpu": "arm64" }, "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.1.5", "", { "os": "linux", "cpu": "ppc64" }, "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.1.5", "", { "os": "linux", "cpu": "s390x" }, "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.1.5", "", { "os": "linux", "cpu": "x64" }, "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.1.5", "", { "os": "none", "cpu": "arm64" }, "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.1.5", "", { "dependencies": { "@emnapi/core": "1.11.1", "@emnapi/runtime": "1.11.1", "@napi-rs/wasm-runtime": "^1.1.6" }, "cpu": "none" }, "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.1.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw=="],
|
||||||
|
|
||||||
|
"@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.1.5", "", { "os": "win32", "cpu": "x64" }, "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA=="],
|
||||||
|
|
||||||
|
"@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.1", "", {}, "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw=="],
|
||||||
|
|
||||||
"@swc/core": ["@swc/core@1.15.43", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.27" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.43", "@swc/core-darwin-x64": "1.15.43", "@swc/core-linux-arm-gnueabihf": "1.15.43", "@swc/core-linux-arm64-gnu": "1.15.43", "@swc/core-linux-arm64-musl": "1.15.43", "@swc/core-linux-ppc64-gnu": "1.15.43", "@swc/core-linux-s390x-gnu": "1.15.43", "@swc/core-linux-x64-gnu": "1.15.43", "@swc/core-linux-x64-musl": "1.15.43", "@swc/core-win32-arm64-msvc": "1.15.43", "@swc/core-win32-ia32-msvc": "1.15.43", "@swc/core-win32-x64-msvc": "1.15.43" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw=="],
|
"@swc/core": ["@swc/core@1.15.43", "", { "dependencies": { "@swc/counter": "^0.1.3", "@swc/types": "^0.1.27" }, "optionalDependencies": { "@swc/core-darwin-arm64": "1.15.43", "@swc/core-darwin-x64": "1.15.43", "@swc/core-linux-arm-gnueabihf": "1.15.43", "@swc/core-linux-arm64-gnu": "1.15.43", "@swc/core-linux-arm64-musl": "1.15.43", "@swc/core-linux-ppc64-gnu": "1.15.43", "@swc/core-linux-s390x-gnu": "1.15.43", "@swc/core-linux-x64-gnu": "1.15.43", "@swc/core-linux-x64-musl": "1.15.43", "@swc/core-win32-arm64-msvc": "1.15.43", "@swc/core-win32-ia32-msvc": "1.15.43", "@swc/core-win32-x64-msvc": "1.15.43" }, "peerDependencies": { "@swc/helpers": ">=0.5.17" }, "optionalPeers": ["@swc/helpers"] }, "sha512-1CuKjFkPxIgGdeHVuNbkxmBxkcbdc08u0aiI43pFq6yY1tTVKmXT9hFEooyyKs/sJ3xf1GPHyEwTtk9Xl8dvQw=="],
|
||||||
|
|
||||||
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.43", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA=="],
|
"@swc/core-darwin-arm64": ["@swc/core-darwin-arm64@1.15.43", "", { "os": "darwin", "cpu": "arm64" }, "sha512-v1aVuvXdo/BHxJzco9V2xpHrvwWmhfS8t6gziY5wJxd+Z2h8AeJRnAwPD8itCDaGXVBwJ/CaKfxEzTkG0Va0OA=="],
|
||||||
@@ -131,6 +174,8 @@
|
|||||||
|
|
||||||
"@temporalio/workflow": ["@temporalio/workflow@1.20.3", "", { "dependencies": { "@temporalio/common": "1.20.3", "@temporalio/proto": "1.20.3", "nexus-rpc": "^0.0.2" } }, "sha512-6LRfnWp3HcvqvKFwbOhs5iDQkHNIM5Rxtxhsi2E5ViPDvJMBqlQ0sQ4oRo5SEgr5Bri650i7GfEQQJMVl7xoKg=="],
|
"@temporalio/workflow": ["@temporalio/workflow@1.20.3", "", { "dependencies": { "@temporalio/common": "1.20.3", "@temporalio/proto": "1.20.3", "nexus-rpc": "^0.0.2" } }, "sha512-6LRfnWp3HcvqvKFwbOhs5iDQkHNIM5Rxtxhsi2E5ViPDvJMBqlQ0sQ4oRo5SEgr5Bri650i7GfEQQJMVl7xoKg=="],
|
||||||
|
|
||||||
|
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.3", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg=="],
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
"@types/bun": ["@types/bun@1.3.14", "", { "dependencies": { "bun-types": "1.3.14" } }, "sha512-h1hFqFVcvAvD9j9K7ZW7vd82aSA+rTdznZa+5bwvCwqSB1jmmfLcbIWhOLx1/+boy/xmjgCs/OMUL8hRJSmnPw=="],
|
||||||
|
|
||||||
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
|
"@types/estree": ["@types/estree@1.0.9", "", {}, "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg=="],
|
||||||
@@ -211,6 +256,8 @@
|
|||||||
|
|
||||||
"commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
"commander": ["commander@2.20.3", "", {}, "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="],
|
||||||
|
|
||||||
|
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
||||||
|
|
||||||
"electron-to-chromium": ["electron-to-chromium@1.5.392", "", {}, "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g=="],
|
"electron-to-chromium": ["electron-to-chromium@1.5.392", "", {}, "sha512-1yQq3VQCZRwsnYc67Oc+1fge6Lwtn0hzi6zmEVkB61Zx21kTbwJAW4dFLadl5Rc1tKhG/kSpYXnfiAhu0f0a1g=="],
|
||||||
|
|
||||||
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
||||||
@@ -235,8 +282,12 @@
|
|||||||
|
|
||||||
"fast-uri": ["fast-uri@3.1.3", "", {}, "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg=="],
|
"fast-uri": ["fast-uri@3.1.3", "", {}, "sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg=="],
|
||||||
|
|
||||||
|
"fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
|
||||||
|
|
||||||
"fs-monkey": ["fs-monkey@1.1.0", "", {}, "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw=="],
|
"fs-monkey": ["fs-monkey@1.1.0", "", {}, "sha512-QMUezzXWII9EV5aTFXW1UBVUO77wYPpjqIF8/AviUCThNeSYZykpoTixUeaNNBwmCev0AMDWMAni+f8Hxb1IFw=="],
|
||||||
|
|
||||||
|
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
|
||||||
|
|
||||||
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
|
||||||
|
|
||||||
"glob-to-regex.js": ["glob-to-regex.js@1.2.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ=="],
|
"glob-to-regex.js": ["glob-to-regex.js@1.2.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ=="],
|
||||||
@@ -257,6 +308,30 @@
|
|||||||
|
|
||||||
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
"json-schema-traverse": ["json-schema-traverse@1.0.0", "", {}, "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="],
|
||||||
|
|
||||||
|
"lightningcss": ["lightningcss@1.32.0", "", { "dependencies": { "detect-libc": "^2.0.3" }, "optionalDependencies": { "lightningcss-android-arm64": "1.32.0", "lightningcss-darwin-arm64": "1.32.0", "lightningcss-darwin-x64": "1.32.0", "lightningcss-freebsd-x64": "1.32.0", "lightningcss-linux-arm-gnueabihf": "1.32.0", "lightningcss-linux-arm64-gnu": "1.32.0", "lightningcss-linux-arm64-musl": "1.32.0", "lightningcss-linux-x64-gnu": "1.32.0", "lightningcss-linux-x64-musl": "1.32.0", "lightningcss-win32-arm64-msvc": "1.32.0", "lightningcss-win32-x64-msvc": "1.32.0" } }, "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ=="],
|
||||||
|
|
||||||
|
"lightningcss-android-arm64": ["lightningcss-android-arm64@1.32.0", "", { "os": "android", "cpu": "arm64" }, "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg=="],
|
||||||
|
|
||||||
|
"lightningcss-darwin-arm64": ["lightningcss-darwin-arm64@1.32.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ=="],
|
||||||
|
|
||||||
|
"lightningcss-darwin-x64": ["lightningcss-darwin-x64@1.32.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w=="],
|
||||||
|
|
||||||
|
"lightningcss-freebsd-x64": ["lightningcss-freebsd-x64@1.32.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm-gnueabihf": ["lightningcss-linux-arm-gnueabihf@1.32.0", "", { "os": "linux", "cpu": "arm" }, "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm64-gnu": ["lightningcss-linux-arm64-gnu@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-arm64-musl": ["lightningcss-linux-arm64-musl@1.32.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-x64-gnu": ["lightningcss-linux-x64-gnu@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA=="],
|
||||||
|
|
||||||
|
"lightningcss-linux-x64-musl": ["lightningcss-linux-x64-musl@1.32.0", "", { "os": "linux", "cpu": "x64" }, "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg=="],
|
||||||
|
|
||||||
|
"lightningcss-win32-arm64-msvc": ["lightningcss-win32-arm64-msvc@1.32.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw=="],
|
||||||
|
|
||||||
|
"lightningcss-win32-x64-msvc": ["lightningcss-win32-x64-msvc@1.32.0", "", { "os": "win32", "cpu": "x64" }, "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q=="],
|
||||||
|
|
||||||
"loader-runner": ["loader-runner@4.3.2", "", {}, "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w=="],
|
"loader-runner": ["loader-runner@4.3.2", "", {}, "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w=="],
|
||||||
|
|
||||||
"lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
|
"lodash.camelcase": ["lodash.camelcase@4.3.0", "", {}, "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA=="],
|
||||||
@@ -275,6 +350,8 @@
|
|||||||
|
|
||||||
"ms": ["ms@3.0.0-canary.1", "", {}, "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g=="],
|
"ms": ["ms@3.0.0-canary.1", "", {}, "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g=="],
|
||||||
|
|
||||||
|
"nanoid": ["nanoid@3.3.16", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q=="],
|
||||||
|
|
||||||
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
|
"neo-async": ["neo-async@2.6.2", "", {}, "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw=="],
|
||||||
|
|
||||||
"nexus-rpc": ["nexus-rpc@0.0.2", "", {}, "sha512-IWjIExdVYlmwXuzHdY/Q3lXCv1gbqoAXPazQhy2w4Xgtgha3H0OOujEESVPQcFUFMWm+pAk2gKnb57g8S41JZg=="],
|
"nexus-rpc": ["nexus-rpc@0.0.2", "", {}, "sha512-IWjIExdVYlmwXuzHdY/Q3lXCv1gbqoAXPazQhy2w4Xgtgha3H0OOujEESVPQcFUFMWm+pAk2gKnb57g8S41JZg=="],
|
||||||
@@ -283,6 +360,10 @@
|
|||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
|
"picomatch": ["picomatch@4.0.5", "", {}, "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A=="],
|
||||||
|
|
||||||
|
"postcss": ["postcss@8.5.19", "", { "dependencies": { "nanoid": "^3.3.12", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ=="],
|
||||||
|
|
||||||
"proto3-json-serializer": ["proto3-json-serializer@2.0.2", "", { "dependencies": { "protobufjs": "^7.2.5" } }, "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ=="],
|
"proto3-json-serializer": ["proto3-json-serializer@2.0.2", "", { "dependencies": { "protobufjs": "^7.2.5" } }, "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ=="],
|
||||||
|
|
||||||
"protobufjs": ["protobufjs@7.6.5", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw=="],
|
"protobufjs": ["protobufjs@7.6.5", "", { "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", "@protobufjs/codegen": "^2.0.5", "@protobufjs/eventemitter": "^1.1.1", "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", "long": "^5.3.2" } }, "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw=="],
|
||||||
@@ -291,6 +372,8 @@
|
|||||||
|
|
||||||
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
"require-from-string": ["require-from-string@2.0.2", "", {}, "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="],
|
||||||
|
|
||||||
|
"rolldown": ["rolldown@1.1.5", "", { "dependencies": { "@oxc-project/types": "=0.139.0", "@rolldown/pluginutils": "^1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.1.5", "@rolldown/binding-darwin-arm64": "1.1.5", "@rolldown/binding-darwin-x64": "1.1.5", "@rolldown/binding-freebsd-x64": "1.1.5", "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", "@rolldown/binding-linux-arm64-gnu": "1.1.5", "@rolldown/binding-linux-arm64-musl": "1.1.5", "@rolldown/binding-linux-ppc64-gnu": "1.1.5", "@rolldown/binding-linux-s390x-gnu": "1.1.5", "@rolldown/binding-linux-x64-gnu": "1.1.5", "@rolldown/binding-linux-x64-musl": "1.1.5", "@rolldown/binding-openharmony-arm64": "1.1.5", "@rolldown/binding-wasm32-wasi": "1.1.5", "@rolldown/binding-win32-arm64-msvc": "1.1.5", "@rolldown/binding-win32-x64-msvc": "1.1.5" }, "bin": { "rolldown": "./bin/cli.mjs" } }, "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA=="],
|
||||||
|
|
||||||
"rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="],
|
"rxjs": ["rxjs@7.8.2", "", { "dependencies": { "tslib": "^2.1.0" } }, "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA=="],
|
||||||
|
|
||||||
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
|
||||||
@@ -319,6 +402,8 @@
|
|||||||
|
|
||||||
"thingies": ["thingies@2.6.0", "", { "peerDependencies": { "tslib": "^2" } }, "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg=="],
|
"thingies": ["thingies@2.6.0", "", { "peerDependencies": { "tslib": "^2" } }, "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg=="],
|
||||||
|
|
||||||
|
"tinyglobby": ["tinyglobby@0.2.17", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g=="],
|
||||||
|
|
||||||
"tree-dump": ["tree-dump@1.1.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA=="],
|
"tree-dump": ["tree-dump@1.1.0", "", { "peerDependencies": { "tslib": "2" } }, "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA=="],
|
||||||
|
|
||||||
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
||||||
@@ -333,6 +418,8 @@
|
|||||||
|
|
||||||
"uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="],
|
"uuid": ["uuid@11.1.1", "", { "bin": { "uuid": "dist/esm/bin/uuid" } }, "sha512-vIYxrBCC/N/K+Js3qSN88go7kIfNPssr/hHCesKCQNAjmgvYS2oqr69kIufEG+O4+PfezOH4EbIeHCfFov8ZgQ=="],
|
||||||
|
|
||||||
|
"vite": ["vite@8.1.5", "", { "dependencies": { "lightningcss": "^1.32.0", "picomatch": "^4.0.5", "postcss": "^8.5.17", "rolldown": "~1.1.5", "tinyglobby": "^0.2.17" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "@vitejs/devtools": "^0.3.0", "esbuild": "^0.27.0 || ^0.28.0", "jiti": ">=1.21.0", "less": "^4.0.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "@vitejs/devtools", "esbuild", "jiti", "less", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7ULLwsCdYx/nRyrpiEwvqb5TFHrMVZyBt+rg/OAXT7rgj/z+DtTDyKFeLAdDkubDVDKD8jOsndmy7m55XcfUsw=="],
|
||||||
|
|
||||||
"watchpack": ["watchpack@2.5.2", "", { "dependencies": { "graceful-fs": "^4.1.2" } }, "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg=="],
|
"watchpack": ["watchpack@2.5.2", "", { "dependencies": { "graceful-fs": "^4.1.2" } }, "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg=="],
|
||||||
|
|
||||||
"webpack": ["webpack@5.108.4", "", { "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.22.2", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "watchpack": "^2.5.2", "webpack-sources": "^3.5.0" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w=="],
|
"webpack": ["webpack@5.108.4", "", { "dependencies": { "@types/estree": "^1.0.8", "@types/json-schema": "^7.0.15", "@webassemblyjs/ast": "^1.14.1", "@webassemblyjs/wasm-edit": "^1.14.1", "@webassemblyjs/wasm-parser": "^1.14.1", "acorn": "^8.16.0", "acorn-import-phases": "^1.0.3", "browserslist": "^4.28.1", "chrome-trace-event": "^1.0.2", "enhanced-resolve": "^5.22.2", "es-module-lexer": "^2.1.0", "eslint-scope": "5.1.1", "events": "^3.2.0", "graceful-fs": "^4.2.11", "loader-runner": "^4.3.2", "mime-db": "^1.54.0", "minimizer-webpack-plugin": "^5.6.1", "neo-async": "^2.6.2", "schema-utils": "^4.3.3", "tapable": "^2.3.0", "watchpack": "^2.5.2", "webpack-sources": "^3.5.0" }, "bin": { "webpack": "bin/webpack.js" } }, "sha512-yur8LyJoeiWh47dErD+Ok7vlbmDsJ3UbbRPAoxbGJ54WpE2y5yVo5G/inUzujnYgw3tPmBRdn+G7PoxXaYC33w=="],
|
||||||
|
|||||||
+11
-8
@@ -87,6 +87,7 @@ temporal:
|
|||||||
runtime:
|
runtime:
|
||||||
secretsRoot: /root/.unidesk/.state/secrets
|
secretsRoot: /root/.unidesk/.state/secrets
|
||||||
secretSourcePaths:
|
secretSourcePaths:
|
||||||
|
/root/.unidesk/.env/unified-admin-password.txt: /root/.unidesk/.env/unified-admin-password.txt
|
||||||
platform-infra/sub2api.env: /root/.unidesk/.state/secrets/platform-infra/sub2api.env
|
platform-infra/sub2api.env: /root/.unidesk/.state/secrets/platform-infra/sub2api.env
|
||||||
platform-infra/apistate.env: /root/.unidesk/.state/secrets/platform-infra/apistate.env
|
platform-infra/apistate.env: /root/.unidesk/.state/secrets/platform-infra/apistate.env
|
||||||
defaultCliTarget: local
|
defaultCliTarget: local
|
||||||
@@ -96,6 +97,7 @@ runtime:
|
|||||||
mode: embedded
|
mode: embedded
|
||||||
databasePath: .state/sub2rank.sqlite
|
databasePath: .state/sub2rank.sqlite
|
||||||
scoreCachePath: .state/account-scores.json
|
scoreCachePath: .state/account-scores.json
|
||||||
|
monitorWorkDir: /root/unidesk
|
||||||
production:
|
production:
|
||||||
mode: http
|
mode: http
|
||||||
baseUrl: https://apistate.hwpod.com
|
baseUrl: https://apistate.hwpod.com
|
||||||
@@ -112,8 +114,8 @@ runtime:
|
|||||||
stateDir: .state/native
|
stateDir: .state/native
|
||||||
env:
|
env:
|
||||||
APISTATE_WEB_PASSWORD:
|
APISTATE_WEB_PASSWORD:
|
||||||
sourceRef: platform-infra/apistate.env
|
sourceRef: /root/.unidesk/.env/unified-admin-password.txt
|
||||||
sourceKey: APISTATE_WEB_PASSWORD
|
sourceKey: contents
|
||||||
APISTATE_API_KEY:
|
APISTATE_API_KEY:
|
||||||
sourceRef: platform-infra/apistate.env
|
sourceRef: platform-infra/apistate.env
|
||||||
sourceKey: APISTATE_API_KEY
|
sourceKey: APISTATE_API_KEY
|
||||||
@@ -150,13 +152,10 @@ runtime:
|
|||||||
logFile: worker.log
|
logFile: worker.log
|
||||||
web:
|
web:
|
||||||
command:
|
command:
|
||||||
- bun
|
- bunx
|
||||||
- --hot
|
- vite
|
||||||
- src/dev-web.ts
|
|
||||||
- --config
|
- --config
|
||||||
- config/sub2rank.yaml
|
- vite.config.ts
|
||||||
- --runtime
|
|
||||||
- native
|
|
||||||
pidFile: web.pid
|
pidFile: web.pid
|
||||||
logFile: web.log
|
logFile: web.log
|
||||||
serverTargets:
|
serverTargets:
|
||||||
@@ -168,8 +167,10 @@ runtime:
|
|||||||
webListenHost: 127.0.0.1
|
webListenHost: 127.0.0.1
|
||||||
webListenPort: 5173
|
webListenPort: 5173
|
||||||
webApiBaseUrl: http://127.0.0.1:8080
|
webApiBaseUrl: http://127.0.0.1:8080
|
||||||
|
secureCookies: false
|
||||||
databasePath: .state/sub2rank.sqlite
|
databasePath: .state/sub2rank.sqlite
|
||||||
scoreCachePath: .state/account-scores.json
|
scoreCachePath: .state/account-scores.json
|
||||||
|
monitorWorkDir: /root/unidesk
|
||||||
adminTokenEnv: APISTATE_API_KEY
|
adminTokenEnv: APISTATE_API_KEY
|
||||||
sub2apiAdminEmailEnv: SUB2API_ADMIN_EMAIL
|
sub2apiAdminEmailEnv: SUB2API_ADMIN_EMAIL
|
||||||
sub2apiAdminPasswordEnv: SUB2API_ADMIN_PASSWORD
|
sub2apiAdminPasswordEnv: SUB2API_ADMIN_PASSWORD
|
||||||
@@ -184,8 +185,10 @@ runtime:
|
|||||||
webListenHost: 127.0.0.1
|
webListenHost: 127.0.0.1
|
||||||
webListenPort: 5173
|
webListenPort: 5173
|
||||||
webApiBaseUrl: http://127.0.0.1:8080
|
webApiBaseUrl: http://127.0.0.1:8080
|
||||||
|
secureCookies: true
|
||||||
databasePath: /var/lib/sub2rank/sub2rank.sqlite
|
databasePath: /var/lib/sub2rank/sub2rank.sqlite
|
||||||
scoreCachePath: /var/lib/sub2rank/account-scores.json
|
scoreCachePath: /var/lib/sub2rank/account-scores.json
|
||||||
|
monitorWorkDir: /opt/unidesk
|
||||||
adminTokenEnv: APISTATE_API_KEY
|
adminTokenEnv: APISTATE_API_KEY
|
||||||
sub2apiAdminEmailEnv: SUB2API_ADMIN_EMAIL
|
sub2apiAdminEmailEnv: SUB2API_ADMIN_EMAIL
|
||||||
sub2apiAdminPasswordEnv: SUB2API_ADMIN_PASSWORD
|
sub2apiAdminPasswordEnv: SUB2API_ADMIN_PASSWORD
|
||||||
|
|||||||
+3
-2
@@ -7,7 +7,7 @@
|
|||||||
"cli": "bun scripts/apistate-cli.ts --config config/sub2rank.yaml",
|
"cli": "bun scripts/apistate-cli.ts --config config/sub2rank.yaml",
|
||||||
"api": "bun --hot src/api.ts --config config/sub2rank.yaml --runtime native",
|
"api": "bun --hot src/api.ts --config config/sub2rank.yaml --runtime native",
|
||||||
"worker": "bun src/worker.ts --config config/sub2rank.yaml --runtime native",
|
"worker": "bun src/worker.ts --config config/sub2rank.yaml --runtime native",
|
||||||
"dev:web": "bun --hot src/dev-web.ts --config config/sub2rank.yaml --runtime native",
|
"dev:web": "APISTATE_CONFIG_PATH=config/sub2rank.yaml APISTATE_RUNTIME_ID=native bunx vite --config vite.config.ts",
|
||||||
"server": "bun src/api.ts --config config/sub2rank.yaml --runtime k8s",
|
"server": "bun src/api.ts --config config/sub2rank.yaml --runtime k8s",
|
||||||
"check": "bunx tsc --noEmit"
|
"check": "bunx tsc --noEmit"
|
||||||
},
|
},
|
||||||
@@ -21,7 +21,8 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "^1.2.21",
|
"@types/bun": "^1.2.21",
|
||||||
"@types/luxon": "^3.7.1",
|
"@types/luxon": "^3.7.1",
|
||||||
"typescript": "^5.9.2"
|
"typescript": "^5.9.2",
|
||||||
|
"vite": "^8.1.5"
|
||||||
},
|
},
|
||||||
"trustedDependencies": [
|
"trustedDependencies": [
|
||||||
"@swc/core",
|
"@swc/core",
|
||||||
|
|||||||
+16
-1
@@ -85,6 +85,7 @@ function help(): Record<string, unknown> {
|
|||||||
"records list|delete",
|
"records list|delete",
|
||||||
"credit test",
|
"credit test",
|
||||||
"api smoke --over-api",
|
"api smoke --over-api",
|
||||||
|
"workflow status --id <workflow-id>",
|
||||||
"native start|stop|status|logs --component api|worker|web [--tail N]",
|
"native start|stop|status|logs --component api|worker|web [--tail N]",
|
||||||
],
|
],
|
||||||
output: "k8s-style text by default; add --json for machine output",
|
output: "k8s-style text by default; add --json for machine output",
|
||||||
@@ -130,6 +131,16 @@ function isAppCommand(value: AppCommand | Record<string, unknown>): value is App
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function embedded(parsed: Parsed, config: ReturnType<typeof loadConfig>, target: EmbeddedCliTarget): Promise<unknown> {
|
async function embedded(parsed: Parsed, config: ReturnType<typeof loadConfig>, target: EmbeddedCliTarget): Promise<unknown> {
|
||||||
|
if (parsed.command.join(" ") === "scores refresh" || parsed.command.join(" ") === "workflow status") {
|
||||||
|
const temporal = await TemporalGateway.connect(config);
|
||||||
|
try {
|
||||||
|
if (parsed.command[0] === "scores") return await temporal.submit({ kind: "scores.refresh" });
|
||||||
|
if (!parsed.id) throw new Error("workflow status requires --id");
|
||||||
|
return await temporal.status(parsed.id);
|
||||||
|
} finally {
|
||||||
|
await temporal.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
const command = appCommand(parsed, config);
|
const command = appCommand(parsed, config);
|
||||||
if (!isAppCommand(command)) return command;
|
if (!isAppCommand(command)) return command;
|
||||||
const context = createEmbeddedContext(config, target);
|
const context = createEmbeddedContext(config, target);
|
||||||
@@ -148,7 +159,11 @@ async function remote(parsed: Parsed, config: ReturnType<typeof loadConfig>, tar
|
|||||||
const [group, action] = parsed.command;
|
const [group, action] = parsed.command;
|
||||||
if (group === "backend" && action === "check") return await client.backendCheck();
|
if (group === "backend" && action === "check") return await client.backendCheck();
|
||||||
if (group === "scores" && action === "get") return await client.scores();
|
if (group === "scores" && action === "get") return await client.scores();
|
||||||
if (group === "scores" && action === "refresh") return await client.refreshScores();
|
if (group === "scores" && action === "refresh") return await client.workflowSubmit({ kind: "scores.refresh" });
|
||||||
|
if (group === "workflow" && action === "status") {
|
||||||
|
if (!parsed.id) throw new Error("workflow status requires --id");
|
||||||
|
return await client.workflowStatus(parsed.id);
|
||||||
|
}
|
||||||
if (group === "lottery" && action === "status") return await client.status();
|
if (group === "lottery" && action === "status") return await client.status();
|
||||||
if (group === "lottery" && action === "draw") return parsed.confirm ? await client.draw() : { ok: true, mutation: false, action: "lottery-draw", hint: "add --confirm to execute" };
|
if (group === "lottery" && action === "draw") return parsed.confirm ? await client.draw() : { ok: true, mutation: false, action: "lottery-draw", hint: "add --confirm to execute" };
|
||||||
if (group === "lottery" && action === "reset") {
|
if (group === "lottery" && action === "reset") {
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ export class AccountScoreService {
|
|||||||
private inFlight: Promise<ScoreSnapshot> | null = null;
|
private inFlight: Promise<ScoreSnapshot> | null = null;
|
||||||
private snapshot: ScoreSnapshot;
|
private snapshot: ScoreSnapshot;
|
||||||
|
|
||||||
constructor(private readonly config: AppConfig, private readonly cachePath: string) {
|
constructor(private readonly config: AppConfig, private readonly cachePath: string, private readonly cliWorkDir: string) {
|
||||||
this.snapshot = this.readCache();
|
this.snapshot = this.readCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ export class AccountScoreService {
|
|||||||
|
|
||||||
private async invoke(scope: string[]): Promise<Record<string, unknown>> {
|
private async invoke(scope: string[]): Promise<Record<string, unknown>> {
|
||||||
const args = [
|
const args = [
|
||||||
resolve(this.config.monitor.cli.workDir, this.config.monitor.cli.entrypoint),
|
resolve(this.cliWorkDir, this.config.monitor.cli.entrypoint),
|
||||||
"platform-infra", "sub2api", "codex-pool", "runtime", "errors",
|
"platform-infra", "sub2api", "codex-pool", "runtime", "errors",
|
||||||
"--target", this.config.monitor.target,
|
"--target", this.config.monitor.target,
|
||||||
"--since", this.config.monitor.scoreWindow,
|
"--since", this.config.monitor.scoreWindow,
|
||||||
@@ -133,7 +133,7 @@ export class AccountScoreService {
|
|||||||
"--raw",
|
"--raw",
|
||||||
];
|
];
|
||||||
const process = Bun.spawn([this.config.monitor.cli.executable, ...args], {
|
const process = Bun.spawn([this.config.monitor.cli.executable, ...args], {
|
||||||
cwd: this.config.monitor.cli.workDir,
|
cwd: this.cliWorkDir,
|
||||||
stdout: "pipe",
|
stdout: "pipe",
|
||||||
stderr: "pipe",
|
stderr: "pipe",
|
||||||
env: { ...Bun.env, UNIDESK_MAIN_SERVER_IP: this.config.monitor.cli.mainServerHost },
|
env: { ...Bun.env, UNIDESK_MAIN_SERVER_IP: this.config.monitor.cli.mainServerHost },
|
||||||
|
|||||||
@@ -38,4 +38,10 @@ export class AdminHttpClient {
|
|||||||
}
|
}
|
||||||
ranking(): Promise<Record<string, unknown>> { return this.request("/api/ranking"); }
|
ranking(): Promise<Record<string, unknown>> { return this.request("/api/ranking"); }
|
||||||
lottery(): Promise<Record<string, unknown>> { return this.request("/api/lottery"); }
|
lottery(): Promise<Record<string, unknown>> { return this.request("/api/lottery"); }
|
||||||
|
workflowSubmit(command: Record<string, unknown>): Promise<Record<string, unknown>> {
|
||||||
|
return this.request("/api/admin/workflows", { method: "POST", body: JSON.stringify({ command }) });
|
||||||
|
}
|
||||||
|
workflowStatus(id: string): Promise<Record<string, unknown>> {
|
||||||
|
return this.request(`/api/admin/workflows/${encodeURIComponent(id)}`);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ const dispatcher = new ApplicationDispatcher({ lottery: context.service, scores:
|
|||||||
const server = Bun.serve({
|
const server = Bun.serve({
|
||||||
hostname: target.listenHost,
|
hostname: target.listenHost,
|
||||||
port: target.listenPort,
|
port: target.listenPort,
|
||||||
fetch: createHandler(dispatcher, config, context.auth, adminToken),
|
fetch: createHandler(dispatcher, config, context.auth, adminToken, target.secureCookies),
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log(JSON.stringify({
|
console.log(JSON.stringify({
|
||||||
|
|||||||
+2
-2
@@ -18,7 +18,7 @@ export interface AppContext {
|
|||||||
export function createEmbeddedContext(config: AppConfig, target: EmbeddedCliTarget): AppContext {
|
export function createEmbeddedContext(config: AppConfig, target: EmbeddedCliTarget): AppContext {
|
||||||
const store = new LotteryStore(config, resolveDataPath(config, target.databasePath));
|
const store = new LotteryStore(config, resolveDataPath(config, target.databasePath));
|
||||||
const client = new Sub2ApiClient(config, readSub2ApiCredentials(config));
|
const client = new Sub2ApiClient(config, readSub2ApiCredentials(config));
|
||||||
const monitor = new AccountScoreService(config, resolveDataPath(config, target.scoreCachePath));
|
const monitor = new AccountScoreService(config, resolveDataPath(config, target.scoreCachePath), target.monitorWorkDir);
|
||||||
return {
|
return {
|
||||||
service: new LotteryService(config, store, client),
|
service: new LotteryService(config, store, client),
|
||||||
store,
|
store,
|
||||||
@@ -39,7 +39,7 @@ export function createServerContext(config: AppConfig, target: ServerTarget): Ap
|
|||||||
}
|
}
|
||||||
const store = new LotteryStore(config, resolveDataPath(config, target.databasePath));
|
const store = new LotteryStore(config, resolveDataPath(config, target.databasePath));
|
||||||
const client = new Sub2ApiClient(config, { email, password });
|
const client = new Sub2ApiClient(config, { email, password });
|
||||||
const monitor = new AccountScoreService(config, resolveDataPath(config, target.scoreCachePath));
|
const monitor = new AccountScoreService(config, resolveDataPath(config, target.scoreCachePath), target.monitorWorkDir);
|
||||||
return {
|
return {
|
||||||
service: new LotteryService(config, store, client),
|
service: new LotteryService(config, store, client),
|
||||||
store,
|
store,
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export interface EmbeddedCliTarget {
|
|||||||
mode: "embedded";
|
mode: "embedded";
|
||||||
databasePath: string;
|
databasePath: string;
|
||||||
scoreCachePath: string;
|
scoreCachePath: string;
|
||||||
|
monitorWorkDir: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface HttpCliTarget {
|
export interface HttpCliTarget {
|
||||||
@@ -96,8 +97,10 @@ export interface ServerTarget {
|
|||||||
webListenHost: string;
|
webListenHost: string;
|
||||||
webListenPort: number;
|
webListenPort: number;
|
||||||
webApiBaseUrl: string;
|
webApiBaseUrl: string;
|
||||||
|
secureCookies: boolean;
|
||||||
databasePath: string;
|
databasePath: string;
|
||||||
scoreCachePath: string;
|
scoreCachePath: string;
|
||||||
|
monitorWorkDir: string;
|
||||||
adminTokenEnv: string;
|
adminTokenEnv: string;
|
||||||
sub2apiAdminEmailEnv: string;
|
sub2apiAdminEmailEnv: string;
|
||||||
sub2apiAdminPasswordEnv: string;
|
sub2apiAdminPasswordEnv: string;
|
||||||
@@ -210,6 +213,7 @@ export function loadConfig(path: string): AppConfig {
|
|||||||
mode,
|
mode,
|
||||||
databasePath: stringValue(target, "databasePath", `runtime.cliTargets.${id}`),
|
databasePath: stringValue(target, "databasePath", `runtime.cliTargets.${id}`),
|
||||||
scoreCachePath: stringValue(target, "scoreCachePath", `runtime.cliTargets.${id}`),
|
scoreCachePath: stringValue(target, "scoreCachePath", `runtime.cliTargets.${id}`),
|
||||||
|
monitorWorkDir: stringValue(target, "monitorWorkDir", `runtime.cliTargets.${id}`),
|
||||||
};
|
};
|
||||||
else if (mode === "http") cliTargets[id] = { mode, baseUrl: stringValue(target, "baseUrl", `runtime.cliTargets.${id}`), adminToken: secretRef(target.adminToken, `runtime.cliTargets.${id}.adminToken`) };
|
else if (mode === "http") cliTargets[id] = { mode, baseUrl: stringValue(target, "baseUrl", `runtime.cliTargets.${id}`), adminToken: secretRef(target.adminToken, `runtime.cliTargets.${id}.adminToken`) };
|
||||||
else throw new Error(`runtime.cliTargets.${id}.mode must be embedded or http`);
|
else throw new Error(`runtime.cliTargets.${id}.mode must be embedded or http`);
|
||||||
@@ -225,8 +229,10 @@ export function loadConfig(path: string): AppConfig {
|
|||||||
webListenHost: stringValue(target, "webListenHost", `runtime.serverTargets.${id}`),
|
webListenHost: stringValue(target, "webListenHost", `runtime.serverTargets.${id}`),
|
||||||
webListenPort: numberValue(target, "webListenPort", `runtime.serverTargets.${id}`, 1),
|
webListenPort: numberValue(target, "webListenPort", `runtime.serverTargets.${id}`, 1),
|
||||||
webApiBaseUrl: stringValue(target, "webApiBaseUrl", `runtime.serverTargets.${id}`),
|
webApiBaseUrl: stringValue(target, "webApiBaseUrl", `runtime.serverTargets.${id}`),
|
||||||
|
secureCookies: booleanValue(target, "secureCookies", `runtime.serverTargets.${id}`),
|
||||||
databasePath: stringValue(target, "databasePath", `runtime.serverTargets.${id}`),
|
databasePath: stringValue(target, "databasePath", `runtime.serverTargets.${id}`),
|
||||||
scoreCachePath: stringValue(target, "scoreCachePath", `runtime.serverTargets.${id}`),
|
scoreCachePath: stringValue(target, "scoreCachePath", `runtime.serverTargets.${id}`),
|
||||||
|
monitorWorkDir: stringValue(target, "monitorWorkDir", `runtime.serverTargets.${id}`),
|
||||||
adminTokenEnv: stringValue(target, "adminTokenEnv", `runtime.serverTargets.${id}`),
|
adminTokenEnv: stringValue(target, "adminTokenEnv", `runtime.serverTargets.${id}`),
|
||||||
sub2apiAdminEmailEnv: stringValue(target, "sub2apiAdminEmailEnv", `runtime.serverTargets.${id}`),
|
sub2apiAdminEmailEnv: stringValue(target, "sub2apiAdminEmailEnv", `runtime.serverTargets.${id}`),
|
||||||
sub2apiAdminPasswordEnv: stringValue(target, "sub2apiAdminPasswordEnv", `runtime.serverTargets.${id}`),
|
sub2apiAdminPasswordEnv: stringValue(target, "sub2apiAdminPasswordEnv", `runtime.serverTargets.${id}`),
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
import { resolve } from "node:path";
|
|
||||||
import { loadConfig } from "./config";
|
|
||||||
import { requiredOption } from "./runtime-args";
|
|
||||||
|
|
||||||
const config = loadConfig(requiredOption("--config"));
|
|
||||||
const runtimeId = requiredOption("--runtime");
|
|
||||||
const target = config.runtime.serverTargets[runtimeId];
|
|
||||||
if (!target) throw new Error(`runtime.serverTargets.${runtimeId} does not exist`);
|
|
||||||
const staticRoot = resolve(import.meta.dir, "../static");
|
|
||||||
|
|
||||||
const contentTypes: Record<string, string> = {
|
|
||||||
".css": "text/css; charset=utf-8",
|
|
||||||
".html": "text/html; charset=utf-8",
|
|
||||||
".js": "text/javascript; charset=utf-8",
|
|
||||||
};
|
|
||||||
|
|
||||||
function staticName(pathname: string): string | null {
|
|
||||||
if (pathname === "/") return "login.html";
|
|
||||||
const value = pathname.slice(1);
|
|
||||||
if (!["login.html", "scores.html", "ranking.html", "lottery.html", "app.js", "styles.css"].includes(value)) return null;
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
const server = Bun.serve({
|
|
||||||
hostname: target.webListenHost,
|
|
||||||
port: target.webListenPort,
|
|
||||||
async fetch(request) {
|
|
||||||
const url = new URL(request.url);
|
|
||||||
if (url.pathname.startsWith("/api/") || url.pathname === "/health") {
|
|
||||||
const upstream = new URL(url.pathname + url.search, target.webApiBaseUrl);
|
|
||||||
return await fetch(new Request(upstream, request));
|
|
||||||
}
|
|
||||||
const pageAlias = ({ "/login": "login.html", "/scores": "scores.html", "/ranking": "ranking.html", "/lottery": "lottery.html" } as Record<string, string>)[url.pathname];
|
|
||||||
const name = pageAlias ?? staticName(url.pathname);
|
|
||||||
if (!name) return Response.json({ ok: false, error: "not found" }, { status: 404 });
|
|
||||||
const file = Bun.file(resolve(staticRoot, name));
|
|
||||||
if (!(await file.exists())) return Response.json({ ok: false, error: "not found" }, { status: 404 });
|
|
||||||
const extension = name.slice(name.lastIndexOf("."));
|
|
||||||
return new Response(file, { headers: { "content-type": contentTypes[extension] ?? "application/octet-stream", "cache-control": "no-store" } });
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
console.log(JSON.stringify({
|
|
||||||
ok: true,
|
|
||||||
component: "apistate-web-native",
|
|
||||||
runtime: runtimeId,
|
|
||||||
listen: server.url.toString(),
|
|
||||||
apiBaseUrl: target.webApiBaseUrl,
|
|
||||||
hotReload: true,
|
|
||||||
valuesPrinted: false,
|
|
||||||
}));
|
|
||||||
|
|
||||||
for (const signal of ["SIGINT", "SIGTERM"] as const) process.on(signal, () => {
|
|
||||||
server.stop(true);
|
|
||||||
process.exit(0);
|
|
||||||
});
|
|
||||||
@@ -37,6 +37,17 @@ export class ApplicationDispatcher {
|
|||||||
if (!this.temporal) throw new Error(`command ${command.kind} requires Temporal`);
|
if (!this.temporal) throw new Error(`command ${command.kind} requires Temporal`);
|
||||||
return await this.temporal.execute(command);
|
return await this.temporal.execute(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async submit(command: AppCommand): Promise<unknown> {
|
||||||
|
if (!usesWorkflow(command)) throw new Error(`command ${command.kind} does not use Temporal`);
|
||||||
|
if (!this.temporal) throw new Error(`command ${command.kind} requires Temporal`);
|
||||||
|
return await this.temporal.submit(command);
|
||||||
|
}
|
||||||
|
|
||||||
|
async workflowStatus(workflowId: string): Promise<unknown> {
|
||||||
|
if (!this.temporal) throw new Error("workflow status requires Temporal");
|
||||||
|
return await this.temporal.status(workflowId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createActivities(services: DispatcherServices): { executeOperation(request: OperationRequest): Promise<unknown> } {
|
export function createActivities(services: DispatcherServices): { executeOperation(request: OperationRequest): Promise<unknown> } {
|
||||||
|
|||||||
+14
-2
@@ -47,6 +47,7 @@ export function createHandler(
|
|||||||
config: AppConfig,
|
config: AppConfig,
|
||||||
auth: WebAuthSecrets,
|
auth: WebAuthSecrets,
|
||||||
legacyAdminToken: string,
|
legacyAdminToken: string,
|
||||||
|
secureCookies: boolean,
|
||||||
): (request: Request) => Promise<Response> {
|
): (request: Request) => Promise<Response> {
|
||||||
return async (request) => {
|
return async (request) => {
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
@@ -60,10 +61,10 @@ export function createHandler(
|
|||||||
if (request.method === "POST" && url.pathname === "/api/login") {
|
if (request.method === "POST" && url.pathname === "/api/login") {
|
||||||
const input = await body(request);
|
const input = await body(request);
|
||||||
if (!validLogin(input.username, input.password, config, auth)) return json({ ok: false, error: "用户名或密码错误" }, 401);
|
if (!validLogin(input.username, input.password, config, auth)) return json({ ok: false, error: "用户名或密码错误" }, 401);
|
||||||
return json({ ok: true, username: config.webAuth.username }, 200, { "set-cookie": createSessionCookie(config, auth) });
|
return json({ ok: true, username: config.webAuth.username }, 200, { "set-cookie": createSessionCookie(config, auth, secureCookies) });
|
||||||
}
|
}
|
||||||
if (request.method === "POST" && url.pathname === "/api/logout") {
|
if (request.method === "POST" && url.pathname === "/api/logout") {
|
||||||
return json({ ok: true }, 200, { "set-cookie": clearSessionCookie(config) });
|
return json({ ok: true }, 200, { "set-cookie": clearSessionCookie(config, secureCookies) });
|
||||||
}
|
}
|
||||||
if ((request.method === "GET" || request.method === "HEAD") && url.pathname === "/login") {
|
if ((request.method === "GET" || request.method === "HEAD") && url.pathname === "/login") {
|
||||||
return session ? redirect("/scores") : await staticFile("login.html", "text/html; charset=utf-8");
|
return session ? redirect("/scores") : await staticFile("login.html", "text/html; charset=utf-8");
|
||||||
@@ -107,6 +108,17 @@ export function createHandler(
|
|||||||
return json(await dispatcher.dispatch({ kind: "records.list", limit }));
|
return json(await dispatcher.dispatch({ kind: "records.list", limit }));
|
||||||
}
|
}
|
||||||
if (request.method === "DELETE" && url.pathname.startsWith("/api/admin/records/")) return json(await dispatcher.dispatch({ kind: "records.delete", id: decodeURIComponent(url.pathname.slice("/api/admin/records/".length)) }));
|
if (request.method === "DELETE" && url.pathname.startsWith("/api/admin/records/")) return json(await dispatcher.dispatch({ kind: "records.delete", id: decodeURIComponent(url.pathname.slice("/api/admin/records/".length)) }));
|
||||||
|
if (request.method === "POST" && url.pathname === "/api/admin/workflows") {
|
||||||
|
const input = await body(request);
|
||||||
|
const command = input.command as Record<string, unknown> | undefined;
|
||||||
|
if (command?.kind !== "scores.refresh") return json({ ok: false, error: "command.kind must be scores.refresh" }, 400);
|
||||||
|
return json(await dispatcher.submit({ kind: "scores.refresh" }));
|
||||||
|
}
|
||||||
|
if (request.method === "GET" && url.pathname.startsWith("/api/admin/workflows/")) {
|
||||||
|
const workflowId = decodeURIComponent(url.pathname.slice("/api/admin/workflows/".length));
|
||||||
|
if (!workflowId) return json({ ok: false, error: "workflow id is required" }, 400);
|
||||||
|
return json(await dispatcher.workflowStatus(workflowId));
|
||||||
|
}
|
||||||
if (request.method === "POST" && url.pathname === "/api/admin/credit-test") {
|
if (request.method === "POST" && url.pathname === "/api/admin/credit-test") {
|
||||||
const input = await body(request);
|
const input = await body(request);
|
||||||
if (typeof input.execute !== "boolean") return json({ ok: false, error: "execute must be boolean" }, 400);
|
if (typeof input.execute !== "boolean") return json({ ok: false, error: "execute must be boolean" }, 400);
|
||||||
|
|||||||
@@ -51,6 +51,8 @@ export function nativeStart(config: AppConfig, component: NativeServiceId): Reco
|
|||||||
rmSync(target.pid, { force: true });
|
rmSync(target.pid, { force: true });
|
||||||
const env: Record<string, string> = { ...process.env } as Record<string, string>;
|
const env: Record<string, string> = { ...process.env } as Record<string, string>;
|
||||||
for (const [targetKey, ref] of Object.entries(config.runtime.native.env)) env[targetKey] = readSecret(config, ref);
|
for (const [targetKey, ref] of Object.entries(config.runtime.native.env)) env[targetKey] = readSecret(config, ref);
|
||||||
|
env.APISTATE_CONFIG_PATH = config.configPath;
|
||||||
|
env.APISTATE_RUNTIME_ID = "native";
|
||||||
const log = openSync(target.log, "a", 0o600);
|
const log = openSync(target.log, "a", 0o600);
|
||||||
try {
|
try {
|
||||||
const child = spawn(service.command[0]!, service.command.slice(1), {
|
const child = spawn(service.command[0]!, service.command.slice(1), {
|
||||||
|
|||||||
+2
-1
@@ -19,7 +19,8 @@ function parseEnv(text: string): Map<string, string> {
|
|||||||
export function readSecret(config: AppConfig, ref: SecretRef): string {
|
export function readSecret(config: AppConfig, ref: SecretRef): string {
|
||||||
const path = config.runtime.secretSourcePaths[ref.sourceRef];
|
const path = config.runtime.secretSourcePaths[ref.sourceRef];
|
||||||
if (!path) throw new Error(`runtime.secretSourcePaths is missing sourceRef ${ref.sourceRef}`);
|
if (!path) throw new Error(`runtime.secretSourcePaths is missing sourceRef ${ref.sourceRef}`);
|
||||||
const value = parseEnv(readFileSync(path, "utf8")).get(ref.sourceKey);
|
const text = readFileSync(path, "utf8");
|
||||||
|
const value = ref.sourceKey === "contents" ? text.trim() : parseEnv(text).get(ref.sourceKey);
|
||||||
if (!value) throw new Error(`secret source ${ref.sourceRef} is missing key ${ref.sourceKey}`);
|
if (!value) throw new Error(`secret source ${ref.sourceRef} is missing key ${ref.sourceKey}`);
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|||||||
+21
-1
@@ -22,8 +22,13 @@ export class TemporalGateway {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async execute(command: AppCommand): Promise<unknown> {
|
async execute(command: AppCommand): Promise<unknown> {
|
||||||
|
const submitted = await this.submit(command);
|
||||||
|
return await this.client.workflow.getHandle(submitted.workflowId).result();
|
||||||
|
}
|
||||||
|
|
||||||
|
async submit(command: AppCommand): Promise<{ ok: true; workflowId: string; runId: string; state: "submitted" }> {
|
||||||
const operation: OperationRequest = { operationId: randomUUID(), command };
|
const operation: OperationRequest = { operationId: randomUUID(), command };
|
||||||
return await this.client.workflow.execute("operationWorkflow", {
|
const handle = await this.client.workflow.start("operationWorkflow", {
|
||||||
taskQueue: this.config.temporal.taskQueue,
|
taskQueue: this.config.temporal.taskQueue,
|
||||||
workflowId: `apistate-${command.kind.replaceAll(".", "-")}-${operation.operationId}`,
|
workflowId: `apistate-${command.kind.replaceAll(".", "-")}-${operation.operationId}`,
|
||||||
workflowExecutionTimeout: this.config.temporal.workflowExecutionTimeout,
|
workflowExecutionTimeout: this.config.temporal.workflowExecutionTimeout,
|
||||||
@@ -33,6 +38,21 @@ export class TemporalGateway {
|
|||||||
maximumAttempts: this.config.temporal.retry.maximumAttempts,
|
maximumAttempts: this.config.temporal.retry.maximumAttempts,
|
||||||
}],
|
}],
|
||||||
});
|
});
|
||||||
|
return { ok: true, workflowId: handle.workflowId, runId: handle.firstExecutionRunId, state: "submitted" };
|
||||||
|
}
|
||||||
|
|
||||||
|
async status(workflowId: string): Promise<Record<string, unknown>> {
|
||||||
|
const handle = this.client.workflow.getHandle(workflowId);
|
||||||
|
const description = await handle.describe();
|
||||||
|
const state = description.status.name.toLocaleLowerCase("en-US");
|
||||||
|
const terminal = ["completed", "failed", "cancelled", "terminated", "timed_out"].includes(state);
|
||||||
|
let result: unknown = null;
|
||||||
|
let error: string | null = null;
|
||||||
|
if (state === "completed") result = await handle.result();
|
||||||
|
else if (terminal) {
|
||||||
|
try { await handle.result(); } catch (caught) { error = caught instanceof Error ? caught.message : String(caught); }
|
||||||
|
}
|
||||||
|
return { ok: state === "completed" || !terminal, workflowId, runId: description.runId, state, terminal, result, error };
|
||||||
}
|
}
|
||||||
|
|
||||||
async ensureScoreSchedule(): Promise<{ started: boolean; workflowId: string }> {
|
async ensureScoreSchedule(): Promise<{ started: boolean; workflowId: string }> {
|
||||||
|
|||||||
+4
-4
@@ -42,17 +42,17 @@ export function sessionAuthorized(request: Request, config: AppConfig, secrets:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createSessionCookie(config: AppConfig, secrets: WebAuthSecrets): string {
|
export function createSessionCookie(config: AppConfig, secrets: WebAuthSecrets, secure: boolean): string {
|
||||||
const payload = Buffer.from(JSON.stringify({
|
const payload = Buffer.from(JSON.stringify({
|
||||||
user: config.webAuth.username,
|
user: config.webAuth.username,
|
||||||
exp: Date.now() + config.webAuth.sessionTtlSeconds * 1000,
|
exp: Date.now() + config.webAuth.sessionTtlSeconds * 1000,
|
||||||
})).toString("base64url");
|
})).toString("base64url");
|
||||||
const value = `${payload}.${signature(payload, secrets.sessionSecret)}`;
|
const value = `${payload}.${signature(payload, secrets.sessionSecret)}`;
|
||||||
return `${config.webAuth.cookieName}=${value}; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=${config.webAuth.sessionTtlSeconds}`;
|
return `${config.webAuth.cookieName}=${value}; Path=/; HttpOnly;${secure ? " Secure;" : ""} SameSite=Strict; Max-Age=${config.webAuth.sessionTtlSeconds}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function clearSessionCookie(config: AppConfig): string {
|
export function clearSessionCookie(config: AppConfig, secure: boolean): string {
|
||||||
return `${config.webAuth.cookieName}=; Path=/; HttpOnly; Secure; SameSite=Strict; Max-Age=0`;
|
return `${config.webAuth.cookieName}=; Path=/; HttpOnly;${secure ? " Secure;" : ""} SameSite=Strict; Max-Age=0`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function validLogin(username: unknown, password: unknown, config: AppConfig, secrets: WebAuthSecrets): boolean {
|
export function validLogin(username: unknown, password: unknown, config: AppConfig, secrets: WebAuthSecrets): boolean {
|
||||||
|
|||||||
@@ -0,0 +1,25 @@
|
|||||||
|
import { defineConfig } from "vite";
|
||||||
|
import { loadConfig } from "./src/config";
|
||||||
|
|
||||||
|
const configPath = process.env.APISTATE_CONFIG_PATH;
|
||||||
|
const runtimeId = process.env.APISTATE_RUNTIME_ID;
|
||||||
|
if (!configPath) throw new Error("Vite requires APISTATE_CONFIG_PATH");
|
||||||
|
if (!runtimeId) throw new Error("Vite requires APISTATE_RUNTIME_ID");
|
||||||
|
|
||||||
|
const config = loadConfig(configPath);
|
||||||
|
const target = config.runtime.serverTargets[runtimeId];
|
||||||
|
if (!target) throw new Error(`runtime.serverTargets.${runtimeId} does not exist`);
|
||||||
|
|
||||||
|
export default defineConfig({
|
||||||
|
root: "static",
|
||||||
|
server: {
|
||||||
|
host: target.webListenHost,
|
||||||
|
port: target.webListenPort,
|
||||||
|
strictPort: true,
|
||||||
|
watch: { usePolling: true, interval: 300 },
|
||||||
|
proxy: {
|
||||||
|
"/api": { target: target.webApiBaseUrl, changeOrigin: true },
|
||||||
|
"/health": { target: target.webApiBaseUrl, changeOrigin: true },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user