From dcf84ae3d1f72adb23469b3b03067dcb582b8cad Mon Sep 17 00:00:00 2001 From: skyy Date: Tue, 25 Aug 2026 16:02:56 -0400 Subject: [PATCH 1/4] chore: add callspec generate:api script and gitignore generated output Prepare for callspec consumer codegen; src/generated/ is build-time only. Co-authored-by: Cursor --- .gitignore | 1 + package.json | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index b947077..a784fd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules/ dist/ +src/generated/ diff --git a/package.json b/package.json index e8e9a06..baed789 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "access": "public" }, "scripts": { + "generate:api": "node node_modules/callspec/dist/cli/generate-client.js ../api-service/callspec.json --output src/generated/api.ts", "build": "tsc", "dev": "tsx src/index.ts", "start": "node dist/index.js", @@ -25,6 +26,7 @@ }, "devDependencies": { "@types/node": "^24.13.2", + "callspec": "3.11.0", "tsx": "4.20.5", "typescript": "5.9.3" }, @@ -34,8 +36,10 @@ "@aws-sdk/client-lambda": "3.997.0", "@aws-sdk/client-sts": "3.997.0", "@inquirer/prompts": "8.3.0", + "callspec": "3.11.0", "commander": "12.1.0", - "open": "10.1.0" + "open": "10.1.0", + "runtyp": "2.5.1" }, "engines": { "node": ">=20.0.0 <25.0.0" From 95ea9be3263c6ed1b71b9fcdd26df044df009005 Mon Sep 17 00:00:00 2001 From: skyy Date: Tue, 25 Aug 2026 16:03:08 -0400 Subject: [PATCH 2/4] chore: lock callspec dependency for generate:api Co-authored-by: Cursor --- package-lock.json | 1082 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 1080 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 041a611..6e1b56f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,14 +13,17 @@ "@aws-sdk/client-lambda": "3.997.0", "@aws-sdk/client-sts": "3.997.0", "@inquirer/prompts": "8.3.0", + "callspec": "3.11.0", "commander": "12.1.0", - "open": "10.1.0" + "open": "10.1.0", + "runtyp": "2.5.1" }, "bin": { "logfox": "dist/index.js" }, "devDependencies": { "@types/node": "^24.13.2", + "callspec": "3.11.0", "tsx": "4.20.5", "typescript": "5.9.3" }, @@ -1246,6 +1249,16 @@ "node": ">=18" } }, + "node_modules/@fontsource-variable/inter": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@fontsource-variable/inter/-/inter-5.3.0.tgz", + "integrity": "sha512-OupL48va4JNofb97w6NYeF9S7W/kHNKM0Er8Dem5nqi4jeOLrVJDoE8tZEpnMJmtkvNbB1EIPPwHcdkF6b1oUA==", + "dev": true, + "license": "OFL-1.1", + "funding": { + "url": "https://github.com/sponsors/ayuhito" + } + }, "node_modules/@inquirer/ansi": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-2.0.3.tgz", @@ -2248,6 +2261,69 @@ "undici-types": "~7.18.0" } }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/body-parser": { + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bytes": "~3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", + "type-is": "~1.6.18", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/bowser": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", @@ -2269,6 +2345,110 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/busboy": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", + "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", + "dev": true, + "dependencies": { + "streamsearch": "^1.1.0" + }, + "engines": { + "node": ">=10.16.0" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callspec": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/callspec/-/callspec-3.11.0.tgz", + "integrity": "sha512-zUewCrWYwHHx+WWyzroY1HtJlY0i1oPPgxQj9cuVi1elI2UcsQk/623wzqtK9BnZ+1I2q0t23eJ4GRoTvDTq7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@fontsource-variable/inter": "^5.3.0", + "busboy": "1.6.0", + "highlight.js": "11.11.1", + "jsout": "^5.0.0-next.3", + "jsout-express": "^1.1.9", + "runtyp": "2.5.0" + }, + "bin": { + "callspec": "dist/cli/generate-client.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "express": "^4.18.0", + "runtyp": "2.5.0" + }, + "peerDependenciesMeta": { + "express": { + "optional": false + }, + "runtyp": { + "optional": false + } + } + }, + "node_modules/callspec/node_modules/runtyp": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/runtyp/-/runtyp-2.5.0.tgz", + "integrity": "sha512-Zgqq7GmjBqTN/8B2upLoZB3SNoM6EaUUbSk35CjzRWKpeg1OCPCv85Oek36SiVZG9A1QWm3rS2tY/bl3JU/mfw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/chardet": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", @@ -2293,6 +2473,61 @@ "node": ">=18" } }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ms": "2.0.0" + } + }, "node_modules/default-browser": { "version": "5.5.0", "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.5.0.tgz", @@ -2333,6 +2568,100 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.25.12", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.12.tgz", @@ -2375,6 +2704,73 @@ "@esbuild/win32-x64": "0.25.12" } }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express": { + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "~1.20.5", + "content-disposition": "~0.5.4", + "content-type": "~1.0.4", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "~0.1.12", + "proxy-addr": "~2.0.7", + "qs": "~6.15.1", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "~0.19.0", + "serve-static": "~1.16.2", + "setprototypeof": "1.2.0", + "statuses": "~2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/fast-string-truncated-width": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", @@ -2417,6 +2813,48 @@ "fxparser": "src/cli/cli.js" } }, + "node_modules/finalhandler": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "~2.4.1", + "parseurl": "~1.3.3", + "statuses": "~2.0.2", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2432,6 +2870,58 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/get-tsconfig": { "version": "4.13.6", "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.6.tgz", @@ -2445,6 +2935,80 @@ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/highlight.js": { + "version": "11.11.1", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.11.1.tgz", + "integrity": "sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/iconv-lite": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz", @@ -2461,6 +3025,25 @@ "url": "https://opencollective.com/express" } }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/is-docker": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", @@ -2509,6 +3092,114 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jsout": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/jsout/-/jsout-5.0.2.tgz", + "integrity": "sha512-vTFcdx3+MMwmVSBv9PXTXT2jBk3MIc25cvIvxIj9wHSgZLsTYgPSCvrR7v7OFFEVlRTuqFNako6evMzajW7J+Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsout-express": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/jsout-express/-/jsout-express-1.1.9.tgz", + "integrity": "sha512-7vOw2k/FqVH3DvkumHd585f/Q/7MluFFFg2EgIfyS+aCzp1GmBkTxqTx4ZXnQY/n4sWMoPPg+LvPw5KfrgqClg==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "express": "*" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "peer": true, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "peer": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT", + "peer": true + }, "node_modules/mute-stream": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-3.0.0.tgz", @@ -2518,6 +3209,45 @@ "node": "^20.17.0 || >=22.9.0" } }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/open": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", @@ -2536,6 +3266,100 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/qs": { + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", + "dev": true, + "license": "BSD-3-Clause", + "peer": true, + "dependencies": { + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-pkg-maps": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", @@ -2558,12 +3382,187 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/runtyp": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/runtyp/-/runtyp-2.5.1.tgz", + "integrity": "sha512-vWJRE8Yx8XBIYjzpLB+bxMadEwo3hAsOE2c/CQ4yCuCHIBJbE80J5zu8KbXJzfq2Cii9J6iDR42AKOMfgTOKXQ==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=5.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "peer": true + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "license": "MIT" }, + "node_modules/send": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "~2.4.1", + "range-parser": "~1.2.1", + "statuses": "~2.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/serve-static": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "~0.19.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC", + "peer": true + }, + "node_modules/side-channel": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -2576,6 +3575,26 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/streamsearch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", + "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/strnum": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.1.2.tgz", @@ -2588,6 +3607,17 @@ ], "license": "MIT" }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">=0.6" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -2614,11 +3644,26 @@ "fsevents": "~2.3.3" } }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/typescript": { "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -2634,6 +3679,39 @@ "integrity": "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==", "devOptional": true, "license": "MIT" + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "peer": true, + "engines": { + "node": ">= 0.8" + } } } } From 9faf8ca37a2e3b73da4bd4348fdeca1f73da6173 Mon Sep 17 00:00:00 2001 From: skyy Date: Tue, 25 Aug 2026 17:02:52 -0400 Subject: [PATCH 3/4] feat: migrate CLI RPC to generated callspec ApiClient Codegen runs at build time from LOGFOX_CALLSPEC_URL or sibling api-service/callspec.json; src/generated/api.ts stays gitignored. Co-authored-by: Cursor --- .github/workflows/ci.yml | 28 +++++ README.md | 9 ++ package-lock.json | 23 +--- package.json | 5 +- scripts/generate-api-client.mjs | 52 +++++++++ src/api.ts | 190 ++++++++++++++++---------------- tsconfig.json | 9 +- 7 files changed, 197 insertions(+), 119 deletions(-) create mode 100644 scripts/generate-api-client.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 2be6cb1..651ed1b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -20,6 +20,12 @@ jobs: node-version: [20, 22, 24] steps: - uses: actions/checkout@v4 + - uses: actions/checkout@v4 + if: ${{ vars.LOGFOX_CALLSPEC_URL == '' }} + with: + repository: logfoxai/api-service + path: api-service + ref: feat/callspec-exports - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} @@ -31,4 +37,26 @@ jobs: echo "@logfoxai:registry=https://npm.pkg.github.com/" > .npmrc echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc - run: npm ci + - name: Emit callspec for CI + if: ${{ vars.LOGFOX_CALLSPEC_URL == '' }} + working-directory: api-service + run: | + npm ci + npx tsx -e " + import {writeFileSync} from 'fs'; + import {emitCallspec} from 'callspec/document'; + import {api} from './src/spec.ts'; + writeFileSync('callspec.json', JSON.stringify(emitCallspec(api.routes, { + title: api.meta.title ?? 'Logfox API', + version: api.meta.version ?? '1.0.0', + basePath: '/v1', + description: api.meta.intro, + exports: api.exports, + visibility: 'all', + }), null, 2) + '\n'); + " + - name: Generate API client + run: npm run generate:api + env: + LOGFOX_CALLSPEC_URL: ${{ vars.LOGFOX_CALLSPEC_URL || format('{0}/api-service/callspec.json', github.workspace) }} - run: npm run build diff --git a/README.md b/README.md index f2c63fb..54f5c39 100644 --- a/README.md +++ b/README.md @@ -62,6 +62,15 @@ logfox config:set appUrl http://localhost:4000 logfox login ``` +Regenerate the typed API client from a running api-service mount (see [api-service](https://github.com/logfoxai/api-service)): + +```bash +npm run generate:api # default: http://127.0.0.1:3000/v1 +LOGFOX_CALLSPEC_URL=https://api.dev.logfox.ai/v1 npm run generate:api +``` + +`src/generated/api.ts` is gitignored — `prebuild` runs codegen before `tsc`. + ## Commits & releases [AutoRel](https://github.com/mhweiner/autorel). Conventional commits — see the [commit format](https://github.com/mhweiner/autorel/blob/main/docs/commit-format.md). diff --git a/package-lock.json b/package-lock.json index 6e1b56f..7817909 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "callspec": "3.11.0", "commander": "12.1.0", "open": "10.1.0", - "runtyp": "2.5.1" + "runtyp": "^2.5.0" }, "bin": { "logfox": "dist/index.js" @@ -2434,21 +2434,6 @@ } } }, - "node_modules/callspec/node_modules/runtyp": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/runtyp/-/runtyp-2.5.0.tgz", - "integrity": "sha512-Zgqq7GmjBqTN/8B2upLoZB3SNoM6EaUUbSk35CjzRWKpeg1OCPCv85Oek36SiVZG9A1QWm3rS2tY/bl3JU/mfw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "typescript": ">=5.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, "node_modules/chardet": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", @@ -3383,9 +3368,9 @@ } }, "node_modules/runtyp": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/runtyp/-/runtyp-2.5.1.tgz", - "integrity": "sha512-vWJRE8Yx8XBIYjzpLB+bxMadEwo3hAsOE2c/CQ4yCuCHIBJbE80J5zu8KbXJzfq2Cii9J6iDR42AKOMfgTOKXQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/runtyp/-/runtyp-2.5.0.tgz", + "integrity": "sha512-Zgqq7GmjBqTN/8B2upLoZB3SNoM6EaUUbSk35CjzRWKpeg1OCPCv85Oek36SiVZG9A1QWm3rS2tY/bl3JU/mfw==", "license": "MIT", "peerDependencies": { "typescript": ">=5.0.0" diff --git a/package.json b/package.json index baed789..5ffbb09 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,8 @@ "access": "public" }, "scripts": { - "generate:api": "node node_modules/callspec/dist/cli/generate-client.js ../api-service/callspec.json --output src/generated/api.ts", + "generate:api": "node scripts/generate-api-client.mjs", + "prebuild": "npm run generate:api", "build": "tsc", "dev": "tsx src/index.ts", "start": "node dist/index.js", @@ -39,7 +40,7 @@ "callspec": "3.11.0", "commander": "12.1.0", "open": "10.1.0", - "runtyp": "2.5.1" + "runtyp": "^2.5.0" }, "engines": { "node": ">=20.0.0 <25.0.0" diff --git a/scripts/generate-api-client.mjs b/scripts/generate-api-client.mjs new file mode 100644 index 0000000..fba0dcd --- /dev/null +++ b/scripts/generate-api-client.mjs @@ -0,0 +1,52 @@ +#!/usr/bin/env node + +import {spawnSync} from 'node:child_process'; +import {existsSync} from 'node:fs'; +import {dirname, join} from 'node:path'; +import {fileURLToPath} from 'node:url'; + +const root = join(dirname(fileURLToPath(import.meta.url)), '..'); +const output = join(root, 'src/generated/api.ts'); +const cli = join(root, 'node_modules/callspec/dist/cli/generate-client.js'); +const siblingCallspec = join(root, '../api-service/callspec.json'); + +function resolveSource() { + + if (process.env.LOGFOX_CALLSPEC_URL) return process.env.LOGFOX_CALLSPEC_URL; + + if (process.env.LOGFOX_CALLSPEC_PATH) return process.env.LOGFOX_CALLSPEC_PATH; + + if (existsSync(siblingCallspec)) return siblingCallspec; + + return undefined; + +} + +const source = resolveSource(); + +if (!source) { + + if (existsSync(output)) { + + console.log('Skipping API codegen — no callspec source and generated client exists'); + process.exit(0); + + } + + console.error('No callspec source. Set LOGFOX_CALLSPEC_PATH or LOGFOX_CALLSPEC_URL, or clone api-service beside cli.'); + process.exit(1); + +} + +const result = spawnSync(process.execPath, [cli, source, '--output', output], { + cwd: root, + stdio: 'inherit', +}); + +if (result.status !== 0) { + + process.exit(result.status ?? 1); + +} + +console.log(`Wrote ${output} from ${source}`); diff --git a/src/api.ts b/src/api.ts index aba4277..3dda5a9 100644 --- a/src/api.ts +++ b/src/api.ts @@ -1,5 +1,18 @@ +import { + ApiClient, + App, + IngestLogsInput, + IngestLogsInputLogsItem, + Team, +} from './generated/api'; import {getConfig} from './config'; +export type {App, Team}; + +export type LogEntry = IngestLogsInputLogsItem & { + data?: Record +}; + type ApiResponse = { ok: true data: T @@ -8,116 +21,125 @@ type ApiResponse = { error: string }; -async function apiCall(method: string, body?: unknown): Promise> { +export type Collector = 'cli' | 'cloudwatch-logs' | 'sdk' | 'vercel' | 'fluentbit'; + +function createClient(): ApiClient | undefined { const config = getConfig(); - const bearer = config.authToken; + const bearer = config.apiKey ?? config.authToken; - if (!bearer) { + if (!bearer) return undefined; - return {ok: false, error: 'Not logged in. Run: logfox login or: logfox config set apiKey '}; + return new ApiClient({ + baseUrl: config.apiUrl, + headers: { + Authorization: `Bearer ${bearer}`, + 'Content-Type': 'application/json', + }, + }); - } +} - try { +function formatError(code: string, data?: unknown): string { - const response = await fetch(`${config.apiUrl}/v1/${method}`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${bearer}`, - }, - body: JSON.stringify(body ?? {}), - }); + if (data && typeof data === 'object' && data !== null && 'message' in data) { - if (!response.ok) { + const message = (data as {message?: string}).message; - const text = await response.text(); - return {ok: false, error: `API error: ${response.status} ${text}`}; + if (message) return message; - } + } - const data = await response.json() as T & {error?: {message?: string}}; + return code; - if ('error' in data && data.error) { +} - return {ok: false, error: data.error.message || String(data.error)}; +function notLoggedIn(): ApiResponse { - } + return {ok: false, error: 'Not logged in. Run: logfox login or: logfox config set apiKey '}; - return {ok: true, data}; +} - } catch (err) { +function normalizeEnv(env: string): IngestLogsInput['env'] { - return {ok: false, error: `Request failed: ${err}`}; + if (env === 'prod') return 'production'; + if (env === 'dev') return 'development'; - } + return env as IngestLogsInput['env']; } -export type App = { - id: string - teamId: string - name: string - createdByUserId?: string - createdAt: string | {__type: string; value: string} - updatedAt: string | {__type: string; value: string} -}; +export async function whoami(): Promise> { -export type Team = { - id: string - name: string -}; + const client = createClient(); -export async function whoami(): Promise> { + if (!client) return notLoggedIn(); - const result = await apiCall<{user: {id: string; email: string}}>('whoami'); + const result = await client.whoami(); - if (!result.ok) return result; + if (result.ok) return {ok: true, data: result.value.user}; - return {ok: true, data: result.data.user}; + return {ok: false, error: formatError(result.code, 'data' in result ? result.data : undefined)}; } export async function getMyTeams(): Promise> { - return apiCall('getMyTeams'); + const client = createClient(); + + if (!client) return notLoggedIn(); + + const result = await client.getMyTeams(); + + if (result.ok) return {ok: true, data: result.value}; + + return {ok: false, error: formatError(result.code, 'data' in result ? result.data : undefined)}; } -export async function searchApps(params: {teamId: string; name?: string; createdByUserId?: string}): Promise> { +export async function searchApps(params: { + teamId: string + name?: string + createdByUserId?: string +}): Promise> { + + const client = createClient(); - return apiCall('searchApps', params); + if (!client) return notLoggedIn(); + + const result = await client.searchApps(params); + + if (result.ok) return {ok: true, data: result.value}; + + return {ok: false, error: formatError(result.code, 'data' in result ? result.data : undefined)}; } export async function createApp(params: {teamId: string; name: string}): Promise> { - return apiCall('createApp', params); + const client = createClient(); -} + if (!client) return notLoggedIn(); -export async function deleteApp(appId: string, teamId: string): Promise> { + const result = await client.createApp(params); + + if (result.ok) return {ok: true, data: result.value}; - return apiCall('deleteApp', {appId, teamId}); + return {ok: false, error: formatError(result.code, 'data' in result ? result.data : undefined)}; } -export type LogEntry = { - timestamp: number - level?: number - message: string - data?: Record -}; +export async function deleteApp(appId: string, teamId: string): Promise> { -export type Collector = 'cli' | 'cloudwatch-logs' | 'sdk' | 'vercel' | 'fluentbit'; + const client = createClient(); -function normalizeEnv(env: string): string { + if (!client) return notLoggedIn(); - if (env === 'prod') return 'production'; - if (env === 'dev') return 'development'; + const result = await client.deleteApp({appId, teamId}); + + if (result.ok) return {ok: true, data: undefined}; - return env; + return {ok: false, error: formatError(result.code, 'data' in result ? result.data : undefined)}; } @@ -131,47 +153,25 @@ export async function ingestLogs( logsIngested: number }>> { - const config = getConfig(); - const bearer = config.apiKey ?? config.authToken; - - if (!bearer) { - - return {ok: false, error: 'Not logged in. Run: logfox login or: logfox config set apiKey '}; - - } - - try { - - const response = await fetch(`${config.apiUrl}/v1/ingestLogs`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Authorization': `Bearer ${bearer}`, - }, - body: JSON.stringify({appId, env: normalizeEnv(env), logs, collector}), - }); + const client = createClient(); - if (!response.ok) { + if (!client) return notLoggedIn(); - const text = await response.text(); - return {ok: false, error: `API error: ${response.status} ${text}`}; + const result = await client.ingestLogs({ + appId, + env: normalizeEnv(env), + logs, + collector, + }); - } + if (result.ok) return {ok: true, data: result.value}; - const data = await response.json() as {success: boolean; logsIngested: number; error?: string}; + if (result.code === 'LOG_INGEST_FAILED') { - if ('error' in data && data.error) { - - return {ok: false, error: data.error}; - - } - - return {ok: true, data}; - - } catch (err) { - - return {ok: false, error: `Request failed: ${err}`}; + return {ok: false, error: result.data.error}; } + return {ok: false, error: formatError(result.code, 'data' in result ? result.data : undefined)}; + } diff --git a/tsconfig.json b/tsconfig.json index f6e1299..05f14f5 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,7 +1,8 @@ { "compilerOptions": { "target": "ES2022", - "module": "commonjs", + "module": "ESNext", + "moduleResolution": "bundler", "lib": ["ES2022"], "outDir": "./dist", "rootDir": "./src", @@ -10,8 +11,10 @@ "skipLibCheck": true, "forceConsistentCasingInFileNames": true, "declaration": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "paths": { + "callspec/client": ["./node_modules/callspec/dist/client.d.ts"] + } }, - "include": ["src/**/*"], "exclude": ["node_modules", "dist"] } From 245a56f48d5568c91cfe0c1de155eaf494453d0e Mon Sep 17 00:00:00 2001 From: skyy Date: Thu, 27 Aug 2026 02:11:27 -0400 Subject: [PATCH 4/4] fix: use callspec CLI with committed CI snapshot like app Drop server/api-service checkout and inline emit script. CI and local codegen read scripts/ci/callspec.json via npx callspec directly. Co-authored-by: Cursor --- .github/workflows/ci.yml | 28 +- README.md | 5 +- package-lock.json | 9 +- package.json | 5 +- scripts/ci/callspec.json | 6430 +++++++++++++++++++++++++++++++ scripts/generate-api-client.mjs | 52 - 6 files changed, 6441 insertions(+), 88 deletions(-) create mode 100644 scripts/ci/callspec.json delete mode 100644 scripts/generate-api-client.mjs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 651ed1b..e37ae86 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,14 +18,10 @@ jobs: fail-fast: false matrix: node-version: [20, 22, 24] + env: + LOGFOX_CALLSPEC_URL: ${{ vars.LOGFOX_CALLSPEC_URL || format('{0}/scripts/ci/callspec.json', github.workspace) }} steps: - uses: actions/checkout@v4 - - uses: actions/checkout@v4 - if: ${{ vars.LOGFOX_CALLSPEC_URL == '' }} - with: - repository: logfoxai/api-service - path: api-service - ref: feat/callspec-exports - uses: actions/setup-node@v6 with: node-version: ${{ matrix.node-version }} @@ -37,26 +33,6 @@ jobs: echo "@logfoxai:registry=https://npm.pkg.github.com/" > .npmrc echo "//npm.pkg.github.com/:_authToken=${{ secrets.GITHUB_TOKEN }}" >> .npmrc - run: npm ci - - name: Emit callspec for CI - if: ${{ vars.LOGFOX_CALLSPEC_URL == '' }} - working-directory: api-service - run: | - npm ci - npx tsx -e " - import {writeFileSync} from 'fs'; - import {emitCallspec} from 'callspec/document'; - import {api} from './src/spec.ts'; - writeFileSync('callspec.json', JSON.stringify(emitCallspec(api.routes, { - title: api.meta.title ?? 'Logfox API', - version: api.meta.version ?? '1.0.0', - basePath: '/v1', - description: api.meta.intro, - exports: api.exports, - visibility: 'all', - }), null, 2) + '\n'); - " - name: Generate API client run: npm run generate:api - env: - LOGFOX_CALLSPEC_URL: ${{ vars.LOGFOX_CALLSPEC_URL || format('{0}/api-service/callspec.json', github.workspace) }} - run: npm run build diff --git a/README.md b/README.md index 54f5c39..09bf50e 100644 --- a/README.md +++ b/README.md @@ -62,11 +62,12 @@ logfox config:set appUrl http://localhost:4000 logfox login ``` -Regenerate the typed API client from a running api-service mount (see [api-service](https://github.com/logfoxai/api-service)): +Regenerate the typed RPC client from the committed CI snapshot (`scripts/ci/callspec.json`) or a live api-service mount: ```bash -npm run generate:api # default: http://127.0.0.1:3000/v1 +npm run generate:api LOGFOX_CALLSPEC_URL=https://api.dev.logfox.ai/v1 npm run generate:api +LOGFOX_CALLSPEC_URL=../server/callspec.json npm run generate:api # sibling server checkout ``` `src/generated/api.ts` is gitignored — `prebuild` runs codegen before `tsc`. diff --git a/package-lock.json b/package-lock.json index 7817909..705be83 100644 --- a/package-lock.json +++ b/package-lock.json @@ -13,7 +13,6 @@ "@aws-sdk/client-lambda": "3.997.0", "@aws-sdk/client-sts": "3.997.0", "@inquirer/prompts": "8.3.0", - "callspec": "3.11.0", "commander": "12.1.0", "open": "10.1.0", "runtyp": "^2.5.0" @@ -23,7 +22,7 @@ }, "devDependencies": { "@types/node": "^24.13.2", - "callspec": "3.11.0", + "callspec": "^3.12.4", "tsx": "4.20.5", "typescript": "5.9.3" }, @@ -2402,9 +2401,9 @@ } }, "node_modules/callspec": { - "version": "3.11.0", - "resolved": "https://registry.npmjs.org/callspec/-/callspec-3.11.0.tgz", - "integrity": "sha512-zUewCrWYwHHx+WWyzroY1HtJlY0i1oPPgxQj9cuVi1elI2UcsQk/623wzqtK9BnZ+1I2q0t23eJ4GRoTvDTq7Q==", + "version": "3.12.4", + "resolved": "https://registry.npmjs.org/callspec/-/callspec-3.12.4.tgz", + "integrity": "sha512-pJVFPoFLnGJ7g1yliw8JawumVC40Jbdu8TOKERDMqMiPXaHiLGs9U/ybGhV5jHe55aLrUe3x/k7acINCvLVtnw==", "dev": true, "license": "MIT", "dependencies": { diff --git a/package.json b/package.json index 5ffbb09..52b82f4 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "access": "public" }, "scripts": { - "generate:api": "node scripts/generate-api-client.mjs", + "generate:api": "callspec \"${LOGFOX_CALLSPEC_URL:-scripts/ci/callspec.json}\" --output src/generated/api.ts", "prebuild": "npm run generate:api", "build": "tsc", "dev": "tsx src/index.ts", @@ -27,7 +27,7 @@ }, "devDependencies": { "@types/node": "^24.13.2", - "callspec": "3.11.0", + "callspec": "^3.12.4", "tsx": "4.20.5", "typescript": "5.9.3" }, @@ -37,7 +37,6 @@ "@aws-sdk/client-lambda": "3.997.0", "@aws-sdk/client-sts": "3.997.0", "@inquirer/prompts": "8.3.0", - "callspec": "3.11.0", "commander": "12.1.0", "open": "10.1.0", "runtyp": "^2.5.0" diff --git a/scripts/ci/callspec.json b/scripts/ci/callspec.json new file mode 100644 index 0000000..c7468f1 --- /dev/null +++ b/scripts/ci/callspec.json @@ -0,0 +1,6430 @@ +{ + "callspec": "2.0", + "info": { + "title": "Logfox API", + "version": "1.0.0", + "description": "Logfox observability API — ingest logs, search logs and issues, and read apps and notification rules. Team API key or session Bearer required on private routes." + }, + "exports": { + "app": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdByUserId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "teamId", + "name", + "createdAt", + "updatedAt" + ], + "additionalProperties": false + }, + "deliveryMethod": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "discord", + "teams", + "github" + ] + }, + "deliveryMethodConfig": { + "oneOf": [ + { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + } + ] + }, + "discordDeliveryMethodConfig": { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + "emailDeliveryMethodConfig": { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "githubDeliveryMethodConfig": { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + }, + "ingestLogEntry": { + "type": "object", + "properties": { + "timestamp": { + "type": "number" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "message": { + "type": "string" + } + }, + "required": [ + "timestamp", + "message" + ] + }, + "issue": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "status": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "isMuted": { + "type": "boolean" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "message": { + "type": "string" + }, + "ftsBlob": { + "type": "string" + }, + "rawLog": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + }, + "occurrences": { + "type": "number" + }, + "lastOccurrence": { + "type": "string", + "format": "date-time" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "dateClosed": { + "type": "string", + "format": "date-time" + }, + "closedByUserId": { + "type": "string" + } + }, + "required": [ + "id", + "teamId", + "appId", + "env", + "status", + "isMuted", + "level", + "message", + "occurrences", + "lastOccurrence", + "createdAt" + ], + "additionalProperties": false + }, + "issueStatus": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "log": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + }, + "logLevel": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "notificationFrequency": { + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly" + ] + }, + "notificationRule": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 16, + "maxLength": 16 + }, + "minItems": 1 + }, + "envs": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "deliveryMethodType": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "discord", + "teams", + "github" + ] + }, + "deliveryMethodConfig": { + "oneOf": [ + { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + } + ] + }, + "frequency": { + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly" + ] + } + }, + "required": [ + "id", + "teamId", + "level", + "deliveryMethodType", + "deliveryMethodConfig", + "frequency" + ], + "additionalProperties": false + }, + "slackDeliveryMethodConfig": { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + "sortOrder": { + "type": "string", + "enum": [ + "asc", + "desc" + ] + }, + "team": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "website": { + "type": "string" + }, + "apiKey": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "createdAt", + "apiKey" + ], + "additionalProperties": false + }, + "teamsDeliveryMethodConfig": { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + "userPublicSafe": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "oneOf": [ + { + "const": "admin" + }, + { + "const": "user" + } + ] + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "createdAt", + "firstName", + "lastName" + ], + "additionalProperties": false + }, + "webhookDeliveryMethodConfig": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + } + }, + "routes": { + "analyzeError": { + "name": "analyzeError", + "path": "/v1/analyzeError", + "method": "POST", + "summary": "Analyze error", + "description": "", + "tags": [ + "logs" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "summary": { + "type": "string" + }, + "diagnosis": { + "type": "string" + }, + "recommended_solution": { + "type": "string" + }, + "logging_improvements": { + "type": "string" + } + }, + "required": [ + "summary", + "diagnosis", + "recommended_solution", + "logging_improvements" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "ANALYSIS_FAILED": { + "status": 400 + } + }, + "mcp": { + "enabled": false + } + }, + "clearBackendCache": { + "name": "clearBackendCache", + "path": "/v1/clearBackendCache", + "method": "POST", + "summary": "Clear backend cache", + "description": "", + "tags": [ + "admin", + "caching" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "output": { + "type": "null" + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "closeAllIssues": { + "name": "closeAllIssues", + "path": "/v1/closeAllIssues", + "method": "POST", + "summary": "Close all issues", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "updatedCount": { + "type": "number" + } + }, + "required": [ + "updatedCount" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "createApp": { + "name": "createApp", + "path": "/v1/createApp", + "method": "POST", + "summary": "Create app", + "description": "", + "tags": [ + "apps" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 3, + "maxLength": 50 + }, + "teamId": { + "type": "string" + } + }, + "required": [ + "name", + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdByUserId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "teamId", + "name", + "createdAt", + "updatedAt" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "APP_ALREADY_EXISTS": { + "status": 400, + "data": {}, + "dataRequired": true + } + }, + "mcp": { + "enabled": false + } + }, + "createTeam": { + "name": "createTeam", + "path": "/v1/createTeam", + "method": "POST", + "summary": "Create team", + "description": "", + "tags": [ + "teams" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "name": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "website": { + "type": "string", + "format": "uri" + } + }, + "required": [ + "name" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "website": { + "type": "string" + }, + "apiKey": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "createdAt", + "apiKey" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "createUserSession": { + "name": "createUserSession", + "path": "/v1/createUserSession", + "method": "POST", + "summary": "Create user session", + "description": "", + "tags": [ + "auth" + ], + "auth": "none", + "scope": "private", + "input": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "maxLength": 100 + } + }, + "required": [ + "email", + "password" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "oneOf": [ + { + "const": "admin" + }, + { + "const": "user" + } + ] + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "createdAt", + "firstName", + "lastName" + ], + "additionalProperties": false + }, + "teams": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "website": { + "type": "string" + }, + "apiKey": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "createdAt", + "apiKey" + ], + "additionalProperties": false + } + } + }, + "required": [ + "token", + "user", + "teams" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "deleteApp": { + "name": "deleteApp", + "path": "/v1/deleteApp", + "method": "POST", + "summary": "Delete app", + "description": "", + "tags": [ + "apps" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + } + }, + "required": [ + "appId", + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "null" + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "destroyUserSessions": { + "name": "destroyUserSessions", + "path": "/v1/destroyUserSessions", + "method": "POST", + "summary": "Destroy user sessions", + "description": "", + "tags": [ + "auth" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "output": { + "type": "null" + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "getAllUsers": { + "name": "getAllUsers", + "path": "/v1/getAllUsers", + "method": "POST", + "summary": "Get all users", + "description": "", + "tags": [ + "admin", + "users" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "oneOf": [ + { + "const": "admin" + }, + { + "const": "user" + } + ] + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "createdAt", + "firstName", + "lastName" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "getIssueById": { + "name": "getIssueById", + "path": "/v1/getIssueById", + "method": "POST", + "summary": "Get issue by ID", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + } + }, + "required": [ + "id", + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "status": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "isMuted": { + "type": "boolean" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "message": { + "type": "string" + }, + "ftsBlob": { + "type": "string" + }, + "rawLog": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + }, + "occurrences": { + "type": "number" + }, + "lastOccurrence": { + "type": "string", + "format": "date-time" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "dateClosed": { + "type": "string", + "format": "date-time" + }, + "closedByUserId": { + "type": "string" + } + }, + "required": [ + "id", + "teamId", + "appId", + "env", + "status", + "isMuted", + "level", + "message", + "occurrences", + "lastOccurrence", + "createdAt" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "getMyTeamMembership": { + "name": "getMyTeamMembership", + "path": "/v1/getMyTeamMembership", + "method": "POST", + "summary": "Get my team membership", + "description": "", + "tags": [ + "teams" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "role": { + "oneOf": [ + { + "const": "manager" + }, + { + "const": "member" + } + ] + } + }, + "required": [ + "role" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "getMyTeams": { + "name": "getMyTeams", + "path": "/v1/getMyTeams", + "method": "POST", + "summary": "Get my teams", + "description": "", + "tags": [ + "teams" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "website": { + "type": "string" + }, + "apiKey": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "createdAt", + "apiKey" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "getNotificationRules": { + "name": "getNotificationRules", + "path": "/v1/getNotificationRules", + "method": "POST", + "summary": "Get notification rules", + "description": "", + "tags": [ + "notifications" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 16, + "maxLength": 16 + }, + "minItems": 1 + }, + "envs": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "deliveryMethodType": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "discord", + "teams", + "github" + ] + }, + "deliveryMethodConfig": { + "oneOf": [ + { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + } + ] + }, + "frequency": { + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly" + ] + } + }, + "required": [ + "id", + "teamId", + "level", + "deliveryMethodType", + "deliveryMethodConfig", + "frequency" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "getNotificationRulesMatchingIssue": { + "name": "getNotificationRulesMatchingIssue", + "path": "/v1/getNotificationRulesMatchingIssue", + "method": "POST", + "summary": "Get matching notification rules", + "description": "", + "tags": [ + "notifications" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "appId": { + "type": "string" + }, + "env": { + "type": "string" + } + }, + "required": [ + "teamId", + "level", + "appId", + "env" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 16, + "maxLength": 16 + }, + "minItems": 1 + }, + "envs": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "deliveryMethodType": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "discord", + "teams", + "github" + ] + }, + "deliveryMethodConfig": { + "oneOf": [ + { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + } + ] + }, + "frequency": { + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly" + ] + } + }, + "required": [ + "id", + "teamId", + "level", + "deliveryMethodType", + "deliveryMethodConfig", + "frequency" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "getNumOpenIssues": { + "name": "getNumOpenIssues", + "path": "/v1/getNumOpenIssues", + "method": "POST", + "summary": "Get open issue counts", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "byEnv": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "count": { + "type": "number" + } + }, + "required": [ + "env", + "count" + ], + "additionalProperties": false + } + }, + "productionBySeverity": { + "type": "array", + "items": { + "type": "object", + "properties": { + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "count": { + "type": "number" + } + }, + "required": [ + "level", + "count" + ], + "additionalProperties": false + } + }, + "byEnvSeverity": { + "type": "array", + "items": { + "type": "object", + "properties": { + "env": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "count": { + "type": "number" + } + }, + "required": [ + "env", + "level", + "count" + ], + "additionalProperties": false + } + } + }, + "required": [ + "byEnv", + "productionBySeverity", + "byEnvSeverity" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "getOpenIssuesByApp": { + "name": "getOpenIssuesByApp", + "path": "/v1/getOpenIssuesByApp", + "method": "POST", + "summary": "Get open issues by app", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "appId": { + "type": "string" + }, + "env": { + "type": "string" + }, + "count": { + "type": "number" + }, + "emergency": { + "type": "number" + }, + "alert": { + "type": "number" + }, + "critical": { + "type": "number" + }, + "error": { + "type": "number" + }, + "warning": { + "type": "number" + } + }, + "required": [ + "appId", + "env", + "count", + "emergency", + "alert", + "critical", + "error", + "warning" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "getRecipientsByTeamId": { + "name": "getRecipientsByTeamId", + "path": "/v1/getRecipientsByTeamId", + "method": "POST", + "summary": "Get recipients by team", + "description": "", + "tags": [ + "users", + "teams" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "firstName", + "lastName" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "getTeamMemberProfile": { + "name": "getTeamMemberProfile", + "path": "/v1/getTeamMemberProfile", + "method": "POST", + "summary": "Get team member profile", + "description": "", + "tags": [ + "users", + "teams" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "userId": { + "type": "string" + }, + "teamId": { + "type": "string" + } + }, + "required": [ + "userId", + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + } + }, + "required": [ + "id", + "email", + "firstName", + "lastName" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "ignoreAllIssues": { + "name": "ignoreAllIssues", + "path": "/v1/ignoreAllIssues", + "method": "POST", + "summary": "Ignore all issues", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "updatedCount": { + "type": "number" + } + }, + "required": [ + "updatedCount" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "ingestLogs": { + "name": "ingestLogs", + "path": "/v1/ingestLogs", + "method": "POST", + "summary": "Ingest logs", + "description": "", + "tags": [ + "logs" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "appId": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "collector": { + "type": "string" + }, + "logs": { + "type": "array", + "items": { + "type": "object", + "properties": { + "timestamp": { + "type": "number" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "message": { + "type": "string" + } + }, + "required": [ + "timestamp", + "message" + ] + } + } + }, + "required": [ + "appId", + "env", + "logs" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "logsIngested": { + "type": "number" + } + }, + "required": [ + "success", + "logsIngested" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "APP_NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "appId": { + "type": "string" + } + }, + "required": [ + "appId" + ], + "additionalProperties": false + }, + "dataRequired": true + }, + "LOG_INGEST_FAILED": { + "status": 400, + "data": { + "type": "object", + "properties": { + "error": { + "type": "string" + } + }, + "required": [ + "error" + ], + "additionalProperties": false + }, + "dataRequired": true + } + }, + "mcp": { + "enabled": false + } + }, + "muteAllIssues": { + "name": "muteAllIssues", + "path": "/v1/muteAllIssues", + "method": "POST", + "summary": "Mute all issues", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + }, + "isMuted": { + "type": "boolean" + } + }, + "required": [ + "teamId", + "isMuted" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "updatedCount": { + "type": "number" + } + }, + "required": [ + "updatedCount" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "register": { + "name": "register", + "path": "/v1/register", + "method": "POST", + "summary": "Register a new account", + "description": "", + "tags": [ + "auth", + "users" + ], + "auth": "none", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamName": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "website": { + "oneOf": [ + { + "type": "string", + "format": "uri" + }, + { + "const": "" + }, + { + "const": " " + } + ] + }, + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string", + "minLength": 8, + "maxLength": 100 + }, + "firstName": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "lastName": { + "type": "string", + "minLength": 1, + "maxLength": 100 + } + }, + "required": [ + "teamName", + "email", + "password", + "firstName", + "lastName" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "token": { + "type": "string" + }, + "team": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "website": { + "type": "string" + }, + "apiKey": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "createdAt", + "apiKey" + ], + "additionalProperties": false + }, + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "oneOf": [ + { + "const": "admin" + }, + { + "const": "user" + } + ] + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "createdAt", + "firstName", + "lastName" + ], + "additionalProperties": false + } + }, + "required": [ + "token", + "team", + "user" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "USER_ALREADY_EXISTS": { + "status": 400 + } + }, + "mcp": { + "enabled": false + } + }, + "renameApp": { + "name": "renameApp", + "path": "/v1/renameApp", + "method": "POST", + "summary": "Rename app", + "description": "", + "tags": [ + "apps" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string", + "minLength": 3, + "maxLength": 50 + }, + "teamId": { + "type": "string" + } + }, + "required": [ + "id", + "name", + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdByUserId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "teamId", + "name", + "createdAt", + "updatedAt" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "resetPassword": { + "name": "resetPassword", + "path": "/v1/resetPassword", + "method": "POST", + "summary": "Reset password", + "description": "", + "tags": [ + "auth" + ], + "auth": "none", + "scope": "private", + "input": { + "type": "object", + "properties": { + "token": { + "type": "string", + "format": "uuid" + }, + "password": { + "type": "string", + "minLength": 8, + "maxLength": 100 + } + }, + "required": [ + "token", + "password" + ], + "additionalProperties": false + }, + "output": { + "type": "null" + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOKEN_NOT_FOUND": { + "status": 400 + }, + "TOKEN_EXPIRED": { + "status": 400 + } + }, + "mcp": { + "enabled": false + } + }, + "searchApps": { + "name": "searchApps", + "path": "/v1/searchApps", + "method": "POST", + "summary": "Search apps", + "description": "", + "tags": [ + "apps" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdByUserId": { + "type": "string" + } + }, + "required": [ + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "name": { + "type": "string" + }, + "createdByUserId": { + "type": "string" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "updatedAt": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "teamId", + "name", + "createdAt", + "updatedAt" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "searchIssues": { + "name": "searchIssues", + "path": "/v1/searchIssues", + "method": "POST", + "summary": "Search issues", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + }, + "vector": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "status": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "isMuted": { + "type": "boolean" + }, + "env": { + "type": "string" + }, + "page": { + "type": "number" + } + }, + "required": [ + "teamId", + "status", + "env" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "status": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "isMuted": { + "type": "boolean" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "message": { + "type": "string" + }, + "ftsBlob": { + "type": "string" + }, + "rawLog": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + }, + "occurrences": { + "type": "number" + }, + "lastOccurrence": { + "type": "string", + "format": "date-time" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "dateClosed": { + "type": "string", + "format": "date-time" + }, + "closedByUserId": { + "type": "string" + } + }, + "required": [ + "id", + "teamId", + "appId", + "env", + "status", + "isMuted", + "level", + "message", + "occurrences", + "lastOccurrence", + "createdAt" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "searchLogs": { + "name": "searchLogs", + "path": "/v1/searchLogs", + "method": "POST", + "summary": "Search logs", + "description": "", + "tags": [ + "logs" + ], + "auth": "bearer", + "scope": "public", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "levelExclusive": { + "type": "boolean" + }, + "startDate": { + "type": "string" + }, + "endDate": { + "type": "string" + }, + "vector": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "env": { + "type": "string" + }, + "page": { + "type": "number" + } + }, + "required": [ + "teamId", + "env" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": true + } + }, + "sendResetPasswordLink": { + "name": "sendResetPasswordLink", + "path": "/v1/sendResetPasswordLink", + "method": "POST", + "summary": "Send password reset link", + "description": "", + "tags": [ + "auth" + ], + "auth": "none", + "scope": "private", + "input": { + "type": "object", + "properties": { + "email": { + "type": "string", + "format": "email" + } + }, + "required": [ + "email" + ], + "additionalProperties": false + }, + "output": { + "type": "null" + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "setNotificationRules": { + "name": "setNotificationRules", + "path": "/v1/setNotificationRules", + "method": "POST", + "summary": "Set notification rules", + "description": "", + "tags": [ + "notifications" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "teamId": { + "type": "string" + }, + "rules": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 16, + "maxLength": 16 + }, + "minItems": 1 + }, + "envs": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "deliveryMethodType": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "discord", + "teams", + "github" + ] + }, + "deliveryMethodConfig": { + "oneOf": [ + { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + } + ] + }, + "frequency": { + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly" + ] + } + }, + "required": [ + "id", + "teamId", + "level", + "deliveryMethodType", + "deliveryMethodConfig", + "frequency" + ], + "additionalProperties": false + } + } + }, + "required": [ + "teamId", + "rules" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appIds": { + "type": "array", + "items": { + "type": "string", + "minLength": 16, + "maxLength": 16 + }, + "minItems": 1 + }, + "envs": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1 + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "deliveryMethodType": { + "type": "string", + "enum": [ + "email", + "webhook", + "slack", + "discord", + "teams", + "github" + ] + }, + "deliveryMethodConfig": { + "oneOf": [ + { + "type": "object", + "properties": { + "userIds": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "headers": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "method": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + }, + "channel": { + "type": "string" + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string", + "minLength": 50 + }, + "username": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "webhookUrl": { + "type": "string" + } + }, + "required": [ + "webhookUrl" + ], + "additionalProperties": false + }, + { + "type": "object", + "properties": { + "repository": { + "type": "string" + }, + "issueLabels": { + "type": "array", + "items": { + "type": "string" + } + }, + "assignees": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "repository" + ], + "additionalProperties": false + } + ] + }, + "frequency": { + "type": "string", + "enum": [ + "hourly", + "daily", + "weekly" + ] + } + }, + "required": [ + "id", + "teamId", + "level", + "deliveryMethodType", + "deliveryMethodConfig", + "frequency" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "updateIssueStatus": { + "name": "updateIssueStatus", + "path": "/v1/updateIssueStatus", + "method": "POST", + "summary": "Update issue status", + "description": "", + "tags": [ + "issues" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "issueIds": { + "type": "array", + "items": { + "type": "string" + }, + "minItems": 1, + "maxItems": 100 + }, + "teamId": { + "type": "string" + }, + "status": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "isMuted": { + "type": "boolean" + } + }, + "required": [ + "issueIds", + "teamId" + ], + "additionalProperties": false + }, + "output": { + "type": "array", + "items": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "status": { + "type": "string", + "enum": [ + "open", + "closed", + "ignored" + ] + }, + "isMuted": { + "type": "boolean" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "message": { + "type": "string" + }, + "ftsBlob": { + "type": "string" + }, + "rawLog": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "appId": { + "type": "string" + }, + "teamId": { + "type": "string" + }, + "message": { + "type": "string" + }, + "level": { + "type": "number", + "minimum": 0, + "maximum": 7 + }, + "data": { + "type": "object", + "properties": {} + }, + "ftsBlob": { + "type": "string" + }, + "env": { + "oneOf": [ + { + "const": "production" + }, + { + "const": "staging" + }, + { + "const": "development" + }, + { + "const": "qa" + }, + { + "const": "local" + }, + { + "const": "test" + } + ] + }, + "rawPayload": { + "oneOf": [ + { + "type": "string" + }, + { + "type": "object", + "properties": {} + } + ] + }, + "collector": { + "type": "string" + }, + "time": { + "type": "string", + "format": "date-time" + } + }, + "required": [ + "id", + "appId", + "teamId", + "message", + "level", + "env", + "time" + ], + "additionalProperties": false + }, + "occurrences": { + "type": "number" + }, + "lastOccurrence": { + "type": "string", + "format": "date-time" + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "dateClosed": { + "type": "string", + "format": "date-time" + }, + "closedByUserId": { + "type": "string" + } + }, + "required": [ + "id", + "teamId", + "appId", + "env", + "status", + "isMuted", + "level", + "message", + "occurrences", + "lastOccurrence", + "createdAt" + ], + "additionalProperties": false + } + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "updateProfile": { + "name": "updateProfile", + "path": "/v1/updateProfile", + "method": "POST", + "summary": "Update profile", + "description": "", + "tags": [ + "users" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": { + "firstName": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "lastName": { + "type": "string", + "minLength": 1, + "maxLength": 100 + }, + "phone": { + "type": "string" + }, + "avatar": { + "type": "string" + }, + "email": { + "type": "string", + "format": "email" + } + }, + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "oneOf": [ + { + "const": "admin" + }, + { + "const": "user" + } + ] + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "createdAt", + "firstName", + "lastName" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + }, + "uploadAvatar": { + "name": "uploadAvatar", + "path": "/v1/uploadAvatar", + "method": "POST", + "summary": "Upload avatar", + "description": "", + "tags": [ + "users" + ], + "auth": "bearer", + "scope": "private", + "encoding": "multipart", + "input": { + "type": "object", + "properties": { + "avatar": { + "type": "string", + "format": "binary" + } + }, + "required": [ + "avatar" + ], + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "UPLOAD_FAILED": { + "status": 400 + } + }, + "mcp": { + "enabled": false + } + }, + "validatePasswordResetToken": { + "name": "validatePasswordResetToken", + "path": "/v1/validatePasswordResetToken", + "method": "POST", + "summary": "Validate password reset token", + "description": "", + "tags": [ + "auth" + ], + "auth": "none", + "scope": "private", + "input": { + "type": "object", + "properties": { + "token": { + "type": "string", + "format": "uuid" + } + }, + "required": [ + "token" + ], + "additionalProperties": false + }, + "output": { + "type": "null" + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOKEN_NOT_FOUND": { + "status": 400 + }, + "TOKEN_EXPIRED": { + "status": 400 + } + }, + "mcp": { + "enabled": false + } + }, + "whoami": { + "name": "whoami", + "path": "/v1/whoami", + "method": "POST", + "summary": "Who am I", + "description": "", + "tags": [ + "auth", + "users" + ], + "auth": "bearer", + "scope": "private", + "input": { + "type": "object", + "properties": {}, + "additionalProperties": false + }, + "output": { + "type": "object", + "properties": { + "user": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "email": { + "type": "string" + }, + "role": { + "oneOf": [ + { + "const": "admin" + }, + { + "const": "user" + } + ] + }, + "createdAt": { + "type": "string", + "format": "date-time" + }, + "avatar": { + "oneOf": [ + { + "type": "string" + }, + { + "const": null + } + ] + }, + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + }, + "required": [ + "id", + "email", + "role", + "createdAt", + "firstName", + "lastName" + ], + "additionalProperties": false + } + }, + "required": [ + "user" + ], + "additionalProperties": false + }, + "errors": { + "NOT_FOUND": { + "status": 404, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "FORBIDDEN": { + "status": 403, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "TOO_MANY_REQUESTS": { + "status": 429, + "data": { + "type": "object", + "properties": { + "title": { + "type": "string" + }, + "message": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + }, + "SERVICE_UNAVAILABLE": { + "status": 503, + "data": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "description": { + "type": "string" + } + }, + "additionalProperties": false + }, + "dataRequired": false + } + }, + "mcp": { + "enabled": false + } + } + } +} \ No newline at end of file diff --git a/scripts/generate-api-client.mjs b/scripts/generate-api-client.mjs deleted file mode 100644 index fba0dcd..0000000 --- a/scripts/generate-api-client.mjs +++ /dev/null @@ -1,52 +0,0 @@ -#!/usr/bin/env node - -import {spawnSync} from 'node:child_process'; -import {existsSync} from 'node:fs'; -import {dirname, join} from 'node:path'; -import {fileURLToPath} from 'node:url'; - -const root = join(dirname(fileURLToPath(import.meta.url)), '..'); -const output = join(root, 'src/generated/api.ts'); -const cli = join(root, 'node_modules/callspec/dist/cli/generate-client.js'); -const siblingCallspec = join(root, '../api-service/callspec.json'); - -function resolveSource() { - - if (process.env.LOGFOX_CALLSPEC_URL) return process.env.LOGFOX_CALLSPEC_URL; - - if (process.env.LOGFOX_CALLSPEC_PATH) return process.env.LOGFOX_CALLSPEC_PATH; - - if (existsSync(siblingCallspec)) return siblingCallspec; - - return undefined; - -} - -const source = resolveSource(); - -if (!source) { - - if (existsSync(output)) { - - console.log('Skipping API codegen — no callspec source and generated client exists'); - process.exit(0); - - } - - console.error('No callspec source. Set LOGFOX_CALLSPEC_PATH or LOGFOX_CALLSPEC_URL, or clone api-service beside cli.'); - process.exit(1); - -} - -const result = spawnSync(process.execPath, [cli, source, '--output', output], { - cwd: root, - stdio: 'inherit', -}); - -if (result.status !== 0) { - - process.exit(result.status ?? 1); - -} - -console.log(`Wrote ${output} from ${source}`);