diff --git a/package.json b/package.json index e6b1bc80..d585279d 100644 --- a/package.json +++ b/package.json @@ -51,7 +51,7 @@ "express": "5.1.0", "express-async-handler": "1.2.0", "express-basic-auth": "1.2.1", - "fast-xml-parser": "5.2.1", + "fast-xml-parser": "5.2.2", "mime-types": "3.0.1", "openpgp": "5.11.2", "pm2": "6.0.5", @@ -71,13 +71,13 @@ "@types/cli-progress": "3.11.6", "@types/express": "5.0.1", "@types/mime-types": "2.1.4", - "@types/node": "22.15.3", + "@types/node": "22.15.16", "@types/range-parser": "1.2.7", - "@vitest/coverage-istanbul": "3.1.2", - "@vitest/spy": "3.1.2", - "eslint": "9.25.1", + "@vitest/coverage-istanbul": "3.1.3", + "@vitest/spy": "3.1.3", + "eslint": "9.26.0", "husky": "9.1.7", - "lint-staged": "15.5.1", + "lint-staged": "15.5.2", "nock": "14.0.4", "nodemon": "3.1.10", "oclif": "4.17.46", @@ -85,7 +85,7 @@ "rimraf": "6.0.1", "ts-node": "10.9.2", "typescript": "5.8.3", - "vitest": "3.1.2", + "vitest": "3.1.3", "vitest-mock-express": "2.2.0" }, "engines": { diff --git a/src/utils/xml.utils.ts b/src/utils/xml.utils.ts index 5eb0054e..c5464401 100644 --- a/src/utils/xml.utils.ts +++ b/src/utils/xml.utils.ts @@ -13,13 +13,13 @@ export class XMLUtils { return builder.build(object); } - static toWebDavXML(object: object, options: XmlBuilderOptions) { + static toWebDavXML(object: object, options: XmlBuilderOptions, rootObject = 'multistatus') { const xmlContent = this.toXML(object, options); return ( '' + - `<${XMLUtils.addDefaultNamespace('multistatus')} xmlns:${XMLUtils.DEFAULT_NAMESPACE_LETTER}="DAV:">` + + `<${XMLUtils.addDefaultNamespace(rootObject)} xmlns:${XMLUtils.DEFAULT_NAMESPACE_LETTER}="DAV:">` + `${xmlContent}` + - `` + `` ); } diff --git a/src/webdav/handlers/PROPFIND.handler.ts b/src/webdav/handlers/PROPFIND.handler.ts index bf28082d..52a50b92 100644 --- a/src/webdav/handlers/PROPFIND.handler.ts +++ b/src/webdav/handlers/PROPFIND.handler.ts @@ -47,7 +47,23 @@ export class PROPFINDRequestHandler implements WebDavMethodHandler { } } } catch { - res.status(207).send(); + res.status(207).send( + XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('response')]: { + [XMLUtils.addDefaultNamespace('href')]: XMLUtils.encodeWebDavUri(resource.url), + [XMLUtils.addDefaultNamespace('propstat')]: { + [XMLUtils.addDefaultNamespace('status')]: 'HTTP/1.1 404 Not Found', + [XMLUtils.addDefaultNamespace('prop')]: {}, + }, + }, + }, + { + ignoreAttributes: false, + suppressEmptyNode: true, + }, + ), + ); } }; diff --git a/src/webdav/middewares/auth.middleware.ts b/src/webdav/middewares/auth.middleware.ts index 298efe77..1b7bcf45 100644 --- a/src/webdav/middewares/auth.middleware.ts +++ b/src/webdav/middewares/auth.middleware.ts @@ -2,6 +2,7 @@ import { RequestHandler } from 'express'; import { SdkManager } from '../../services/sdk-manager.service'; import { AuthService } from '../../services/auth.service'; import { webdavLogger } from '../../utils/logger.utils'; +import { XMLUtils } from '../../utils/xml.utils'; export const AuthMiddleware = (authService: AuthService): RequestHandler => { return (req, res, next) => { @@ -18,8 +19,21 @@ export const AuthMiddleware = (authService: AuthService): RequestHandler => { }; next(); } catch (error) { - webdavLogger.error('Error from AuthMiddleware: ' + (error as Error).message); - res.status(401).send({ error: (error as Error).message }); + let message = 'Authentication required to access this resource.'; + if ('message' in (error as Error) && (error as Error).message.trim().length > 0) { + message = (error as Error).message; + } + + webdavLogger.error('Error from AuthMiddleware: ' + message); + + const errorBodyXML = XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: message, + }, + {}, + 'error', + ); + res.status(401).send(errorBodyXML); } })(); }; diff --git a/src/webdav/middewares/errors.middleware.ts b/src/webdav/middewares/errors.middleware.ts index ae94ab57..98f80d50 100644 --- a/src/webdav/middewares/errors.middleware.ts +++ b/src/webdav/middewares/errors.middleware.ts @@ -1,20 +1,23 @@ import { ErrorRequestHandler } from 'express'; import { webdavLogger } from '../../utils/logger.utils'; +import { XMLUtils } from '../../utils/xml.utils'; // eslint-disable-next-line @typescript-eslint/no-unused-vars export const ErrorHandlingMiddleware: ErrorRequestHandler = (err, req, res, _) => { webdavLogger.error(`[ERROR MIDDLEWARE] [${req.method.toUpperCase()} - ${req.url}]`, err); - if ('statusCode' in err) { - res.status(err.statusCode as number).send({ - error: { - message: err.message, - }, - }); - } else { - res.status(500).send({ - error: { - message: 'message' in err ? err.message : 'Something went wrong', - }, - }); + + const errorBodyXML = XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: 'message' in err ? err.message : 'Something went wrong', + }, + {}, + 'error', + ); + + let statusCode = 500; + if ('statusCode' in err && !isNaN(err.statusCode)) { + statusCode = err.statusCode; } + + res.status(statusCode).send(errorBodyXML); }; diff --git a/src/webdav/webdav-server.ts b/src/webdav/webdav-server.ts index 5fe45f62..3eeda4cb 100644 --- a/src/webdav/webdav-server.ts +++ b/src/webdav/webdav-server.ts @@ -66,8 +66,7 @@ export class WebDavServer { return networkFacade; }; - private readonly registerMiddlewares = async () => { - this.app.use(ErrorHandlingMiddleware); + private readonly registerStartMiddlewares = () => { this.app.use(AuthMiddleware(AuthService.instance)); this.app.use( RequestLoggerMiddleware({ @@ -78,6 +77,10 @@ export class WebDavServer { this.app.use(MkcolMiddleware); }; + private readonly registerEndMiddleWares = () => { + this.app.use(ErrorHandlingMiddleware); + }; + private readonly registerHandlers = async () => { const serverListenPath = /(.*)/; const networkFacade = await this.getNetworkFacade(); @@ -159,8 +162,9 @@ export class WebDavServer { start = async () => { const configs = await this.configService.readWebdavConfig(); this.app.disable('x-powered-by'); - await this.registerMiddlewares(); + this.registerStartMiddlewares(); await this.registerHandlers(); + this.registerEndMiddleWares(); const plainHttp = configs.protocol === 'http'; let server: http.Server | https.Server; diff --git a/test/webdav/middlewares/auth.middleware.test.ts b/test/webdav/middlewares/auth.middleware.test.ts index 064bde6a..8068799c 100644 --- a/test/webdav/middlewares/auth.middleware.test.ts +++ b/test/webdav/middlewares/auth.middleware.test.ts @@ -4,6 +4,7 @@ import { createWebDavRequestFixture, createWebDavResponseFixture } from '../../f import { UserCredentialsFixture } from '../../fixtures/login.fixture'; import { AuthService } from '../../../src/services/auth.service'; import { MissingCredentialsError } from '../../../src/types/command.types'; +import { XMLUtils } from '../../../src/utils/xml.utils'; describe('Auth middleware', () => { beforeEach(() => { @@ -28,7 +29,15 @@ describe('Auth middleware', () => { expect(authServiceStub).toHaveBeenCalledOnce(); expect(next).not.toHaveBeenCalled(); expect(res.status).toHaveBeenCalledWith(401); - expect(res.send).toHaveBeenCalledWith({ error: new MissingCredentialsError().message }); + expect(res.send).toHaveBeenCalledWith( + XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: new MissingCredentialsError().message, + }, + {}, + 'error', + ), + ); }); it('When the user is authenticated, then it should add the user to the request', async () => { diff --git a/test/webdav/middlewares/errors.middleware.test.ts b/test/webdav/middlewares/errors.middleware.test.ts index 47afccf7..2edc5d37 100644 --- a/test/webdav/middlewares/errors.middleware.test.ts +++ b/test/webdav/middlewares/errors.middleware.test.ts @@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { ErrorHandlingMiddleware } from '../../../src/webdav/middewares/errors.middleware'; import { createWebDavRequestFixture, createWebDavResponseFixture } from '../../fixtures/webdav.fixture'; import { BadRequestError, NotFoundError, NotImplementedError } from '../../../src/utils/errors.utils'; +import { XMLUtils } from '../../../src/utils/xml.utils'; describe('Error handling middleware', () => { beforeEach(() => { @@ -9,6 +10,7 @@ describe('Error handling middleware', () => { }); it('When a not found error is received, should respond with a 404', () => { + const errorMessage = 'Item not found'; const error = new NotFoundError('Item not found'); const res = createWebDavResponseFixture({ status: vi.fn().mockReturnValue({ send: vi.fn() }), @@ -21,11 +23,20 @@ describe('Error handling middleware', () => { ErrorHandlingMiddleware(error, req, res, () => {}); expect(res.status).toHaveBeenCalledWith(404); - expect(res.send).toHaveBeenCalledWith({ error: { message: 'Item not found' } }); + expect(res.send).toHaveBeenCalledWith( + XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: errorMessage, + }, + {}, + 'error', + ), + ); }); it('When a bad request error is received, should respond with a 400', () => { - const error = new BadRequestError('Missing property "size"'); + const errorMessage = 'Missing property "size"'; + const error = new BadRequestError(errorMessage); const res = createWebDavResponseFixture({ status: vi.fn().mockReturnValue({ send: vi.fn() }), }); @@ -37,11 +48,20 @@ describe('Error handling middleware', () => { ErrorHandlingMiddleware(error, req, res, () => {}); expect(res.status).toHaveBeenCalledWith(400); - expect(res.send).toHaveBeenCalledWith({ error: { message: 'Missing property "size"' } }); + expect(res.send).toHaveBeenCalledWith( + XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: errorMessage, + }, + {}, + 'error', + ), + ); }); it('When a not implement error is received, should respond with a 501', () => { - const error = new NotImplementedError('Content-range is not supported'); + const errorMessage = 'Content-range is not supported'; + const error = new NotImplementedError(errorMessage); const res = createWebDavResponseFixture({ status: vi.fn().mockReturnValue({ send: vi.fn() }), }); @@ -53,11 +73,20 @@ describe('Error handling middleware', () => { ErrorHandlingMiddleware(error, req, res, () => {}); expect(res.status).toHaveBeenCalledWith(501); - expect(res.send).toHaveBeenCalledWith({ error: { message: 'Content-range is not supported' } }); + expect(res.send).toHaveBeenCalledWith( + XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: errorMessage, + }, + {}, + 'error', + ), + ); }); it('When something that does not have status code arrives, should return a 500 status code', () => { - const error = new TypeError('Cannot read property "id" of undefined'); + const errorMessage = 'Cannot read property "id" of undefined'; + const error = new TypeError(errorMessage); const res = createWebDavResponseFixture({ status: vi.fn().mockReturnValue({ send: vi.fn() }), }); @@ -69,6 +98,14 @@ describe('Error handling middleware', () => { ErrorHandlingMiddleware(error, req, res, () => {}); expect(res.status).toHaveBeenCalledWith(500); - expect(res.send).toHaveBeenCalledWith({ error: { message: 'Cannot read property "id" of undefined' } }); + expect(res.send).toHaveBeenCalledWith( + XMLUtils.toWebDavXML( + { + [XMLUtils.addDefaultNamespace('responsedescription')]: errorMessage, + }, + {}, + 'error', + ), + ); }); }); diff --git a/yarn.lock b/yarn.lock index d75bcf0d..39edc7f7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -949,10 +949,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@9.25.1": - version "9.25.1" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.25.1.tgz#25f5c930c2b68b5ebe7ac857f754cbd61ef6d117" - integrity sha512-dEIwmjntEx8u3Uvv+kr3PDeeArL8Hw07H9kyYxCjnM9pBjfEhk6uLXSchxxzgiwtRhhzVzqmUSDFBOi1TuZ7qg== +"@eslint/js@9.26.0": + version "9.26.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.26.0.tgz#1e13126b67a3db15111d2dcc61f69a2acff70bd5" + integrity sha512-I9XlJawFdSMvWjDt6wksMCrgns5ggLNfFwFvnShsleWruvXM514Qxk8V246efTw+eo9JABvVz+u3q2RiAowKxQ== "@eslint/object-schema@^2.1.6": version "2.1.6" @@ -1419,6 +1419,22 @@ resolved "https://registry.yarnpkg.com/@mattiasbuelens/web-streams-adapter/-/web-streams-adapter-0.1.0.tgz#607b5a25682f4ae2741da7ba6df39302505336b3" integrity sha512-oV4PyZfwJNtmFWhvlJLqYIX1Nn22ML8FZpS16ZUKv0hg7414xV1fjsGqxQzLT2dyK92TKxsJSwMOd7VNHAtPmA== +"@modelcontextprotocol/sdk@^1.8.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@modelcontextprotocol/sdk/-/sdk-1.11.0.tgz#9f1762efe6f3365f0bf3b019cc9bd1629d19bc50" + integrity sha512-k/1pb70eD638anoi0e8wUGAlbMJXyvdV4p62Ko+EZ7eBe1xMx8Uhak1R5DgfoofsK5IBBnRwsYGTaLZl+6/+RQ== + dependencies: + content-type "^1.0.5" + cors "^2.8.5" + cross-spawn "^7.0.3" + eventsource "^3.0.2" + express "^5.0.1" + express-rate-limit "^7.5.0" + pkce-challenge "^5.0.0" + raw-body "^3.0.0" + zod "^3.23.8" + zod-to-json-schema "^3.24.1" + "@mswjs/interceptors@^0.38.5": version "0.38.6" resolved "https://registry.yarnpkg.com/@mswjs/interceptors/-/interceptors-0.38.6.tgz#0646060b5572ff884cf475af90505e757115eddf" @@ -2388,10 +2404,10 @@ dependencies: undici-types "~6.21.0" -"@types/node@22.15.3": - version "22.15.3" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.3.tgz#b7fb9396a8ec5b5dfb1345d8ac2502060e9af68b" - integrity sha512-lX7HFZeHf4QG/J7tBZqrCAXwz9J5RD56Y6MpP0eJkka8p+K0RY/yBTW7CYFJ4VGCclxqOLKmiGP5juQc6MKgcw== +"@types/node@22.15.16": + version "22.15.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.16.tgz#685cf0338ad9f5b14860f50a6ac2c3ebd58582cd" + integrity sha512-3pr+KjwpVujqWqOKT8mNR+rd09FqhBLwg+5L/4t0cNYBzm/yEiYGCxWttjaPBsLtAo+WFNoXzGJfolM1JuRXoA== dependencies: undici-types "~6.21.0" @@ -2518,10 +2534,10 @@ "@typescript-eslint/types" "8.31.0" eslint-visitor-keys "^4.2.0" -"@vitest/coverage-istanbul@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/coverage-istanbul/-/coverage-istanbul-3.1.2.tgz#0fcc2067a9e71cfae2a988a6f34600a404f95b02" - integrity sha512-PXjSd4g7SxlC9WJ00jbMMFJob+LcjXUYow5vpXuZe/acjhlEQgCaf6npm+W9Mg/ahiFKtIAHI+P8A9n2JfZilg== +"@vitest/coverage-istanbul@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/coverage-istanbul/-/coverage-istanbul-3.1.3.tgz#51b52bf1dae6f9117e7672a9ba96e025a56d16dd" + integrity sha512-S6zpofFh7ykVM01KpCbsdPRKBG4SCP/ErvrakFBJEUhiN/nRgsuCsi68VSe8rWstz6V1cJ/Sa/PDttr6FRZuNg== dependencies: "@istanbuljs/schema" "^0.1.3" debug "^4.4.0" @@ -2534,62 +2550,62 @@ test-exclude "^7.0.1" tinyrainbow "^2.0.0" -"@vitest/expect@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.1.2.tgz#b203a7ad2efa6af96c85f6c116216bda259d2bc8" - integrity sha512-O8hJgr+zREopCAqWl3uCVaOdqJwZ9qaDwUP7vy3Xigad0phZe9APxKhPcDNqYYi0rX5oMvwJMSCAXY2afqeTSA== +"@vitest/expect@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/expect/-/expect-3.1.3.tgz#bbca175cd2f23d7de9448a215baed8f3d7abd7b7" + integrity sha512-7FTQQuuLKmN1Ig/h+h/GO+44Q1IlglPlR2es4ab7Yvfx+Uk5xsv+Ykk+MEt/M2Yn/xGmzaLKxGw2lgy2bwuYqg== dependencies: - "@vitest/spy" "3.1.2" - "@vitest/utils" "3.1.2" + "@vitest/spy" "3.1.3" + "@vitest/utils" "3.1.3" chai "^5.2.0" tinyrainbow "^2.0.0" -"@vitest/mocker@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-3.1.2.tgz#1ff239036072feb543ab56825ada09b12a075af2" - integrity sha512-kOtd6K2lc7SQ0mBqYv/wdGedlqPdM/B38paPY+OwJ1XiNi44w3Fpog82UfOibmHaV9Wod18A09I9SCKLyDMqgw== +"@vitest/mocker@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/mocker/-/mocker-3.1.3.tgz#121d0f2fcca20c9ccada9e2d6e761f7fc687f4ce" + integrity sha512-PJbLjonJK82uCWHjzgBJZuR7zmAOrSvKk1QBxrennDIgtH4uK0TB1PvYmc0XBCigxxtiAVPfWtAdy4lpz8SQGQ== dependencies: - "@vitest/spy" "3.1.2" + "@vitest/spy" "3.1.3" estree-walker "^3.0.3" magic-string "^0.30.17" -"@vitest/pretty-format@3.1.2", "@vitest/pretty-format@^3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-3.1.2.tgz#689b0604c0b73fdccb144f11b64d70c9233b23b8" - integrity sha512-R0xAiHuWeDjTSB3kQ3OQpT8Rx3yhdOAIm/JM4axXxnG7Q/fS8XUwggv/A4xzbQA+drYRjzkMnpYnOGAc4oeq8w== +"@vitest/pretty-format@3.1.3", "@vitest/pretty-format@^3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/pretty-format/-/pretty-format-3.1.3.tgz#760b9eab5f253d7d2e7dcd28ef34570f584023d4" + integrity sha512-i6FDiBeJUGLDKADw2Gb01UtUNb12yyXAqC/mmRWuYl+m/U9GS7s8us5ONmGkGpUUo7/iAYzI2ePVfOZTYvUifA== dependencies: tinyrainbow "^2.0.0" -"@vitest/runner@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-3.1.2.tgz#ffeba74618046221e944e94f09b565af772170cf" - integrity sha512-bhLib9l4xb4sUMPXnThbnhX2Yi8OutBMA8Yahxa7yavQsFDtwY/jrUZwpKp2XH9DhRFJIeytlyGpXCqZ65nR+g== +"@vitest/runner@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/runner/-/runner-3.1.3.tgz#b268fa90fca38fab363f1107f057c0a2a141ee45" + integrity sha512-Tae+ogtlNfFei5DggOsSUvkIaSuVywujMj6HzR97AHK6XK8i3BuVyIifWAm/sE3a15lF5RH9yQIrbXYuo0IFyA== dependencies: - "@vitest/utils" "3.1.2" + "@vitest/utils" "3.1.3" pathe "^2.0.3" -"@vitest/snapshot@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-3.1.2.tgz#46c52a417afbf1fe94fba0a5735cbedf9cfc60f6" - integrity sha512-Q1qkpazSF/p4ApZg1vfZSQ5Yw6OCQxVMVrLjslbLFA1hMDrT2uxtqMaw8Tc/jy5DLka1sNs1Y7rBcftMiaSH/Q== +"@vitest/snapshot@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/snapshot/-/snapshot-3.1.3.tgz#39a8f9f8c6ba732ffde59adeacf0a549bef11e76" + integrity sha512-XVa5OPNTYUsyqG9skuUkFzAeFnEzDp8hQu7kZ0N25B1+6KjGm4hWLtURyBbsIAOekfWQ7Wuz/N/XXzgYO3deWQ== dependencies: - "@vitest/pretty-format" "3.1.2" + "@vitest/pretty-format" "3.1.3" magic-string "^0.30.17" pathe "^2.0.3" -"@vitest/spy@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-3.1.2.tgz#3a5be04d71c4a458c8d6859503626e2aed61bcbf" - integrity sha512-OEc5fSXMws6sHVe4kOFyDSj/+4MSwst0ib4un0DlcYgQvRuYQ0+M2HyqGaauUMnjq87tmUaMNDxKQx7wNfVqPA== +"@vitest/spy@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/spy/-/spy-3.1.3.tgz#ca81e2b4f0c3d6c75f35defa77c3336f39c8f605" + integrity sha512-x6w+ctOEmEXdWaa6TO4ilb7l9DxPR5bwEb6hILKuxfU1NqWT2mpJD9NJN7t3OTfxmVlOMrvtoFJGdgyzZ605lQ== dependencies: tinyspy "^3.0.2" -"@vitest/utils@3.1.2": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-3.1.2.tgz#f3ae55b3a205c88c346a2a8dcde7c89210364932" - integrity sha512-5GGd0ytZ7BH3H6JTj9Kw7Prn1Nbg0wZVrIvou+UWxm54d+WoXXgAgjFJ8wn3LdagWLFSEfpPeyYrByZaGEZHLg== +"@vitest/utils@3.1.3": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-3.1.3.tgz#4f31bdfd646cd82d30bfa730d7410cb59d529669" + integrity sha512-2Ltrpht4OmHO9+c/nmHtF09HWiyWdworqnHIwjfvDyWjuwKbdkcS9AnhsDn+8E2RM4x++foD1/tNuLPVvWG1Rg== dependencies: - "@vitest/pretty-format" "3.1.2" + "@vitest/pretty-format" "3.1.3" loupe "^3.1.3" tinyrainbow "^2.0.0" @@ -3305,6 +3321,14 @@ cookie@^0.7.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== +cors@^2.8.5: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + create-require@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" @@ -3675,7 +3699,7 @@ es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-module-lexer@^1.6.0: +es-module-lexer@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.7.0.tgz#9159601561880a85f2734560a9099b2c31e5372a" integrity sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA== @@ -3793,10 +3817,10 @@ eslint-visitor-keys@^4.2.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== -eslint@9.25.1: - version "9.25.1" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.25.1.tgz#8a7cf8dd0e6acb858f86029720adb1785ee57580" - integrity sha512-E6Mtz9oGQWDCpV12319d59n4tx9zOTXSTmc8BLVxBx+G/0RdM5MvEEJLU9c0+aleoePYYgVTOsRblx433qmhWQ== +eslint@9.26.0: + version "9.26.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.26.0.tgz#978fe029adc2aceed28ab437bca876e83461c3b4" + integrity sha512-Hx0MOjPh6uK9oq9nVsATZKE/Wlbai7KFjfCuw9UHaguDW3x+HF0O5nIi3ud39TWgrTjTO5nHxmL3R1eANinWHQ== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.12.1" @@ -3804,11 +3828,12 @@ eslint@9.25.1: "@eslint/config-helpers" "^0.2.1" "@eslint/core" "^0.13.0" "@eslint/eslintrc" "^3.3.1" - "@eslint/js" "9.25.1" + "@eslint/js" "9.26.0" "@eslint/plugin-kit" "^0.2.8" "@humanfs/node" "^0.16.6" "@humanwhocodes/module-importer" "^1.0.1" "@humanwhocodes/retry" "^0.4.2" + "@modelcontextprotocol/sdk" "^1.8.0" "@types/estree" "^1.0.6" "@types/json-schema" "^7.0.15" ajv "^6.12.4" @@ -3833,6 +3858,7 @@ eslint@9.25.1: minimatch "^3.1.2" natural-compare "^1.4.0" optionator "^0.9.3" + zod "^3.24.2" espree@^10.0.1, espree@^10.3.0: version "10.3.0" @@ -3899,6 +3925,18 @@ eventemitter3@^5.0.1: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" integrity sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA== +eventsource-parser@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eventsource-parser/-/eventsource-parser-3.0.1.tgz#5e358dba9a55ba64ca90da883c4ca35bd82467bd" + integrity sha512-VARTJ9CYeuQYb0pZEPbzi740OWFgpHe7AYJ2WFZVnUDUQp5Dk2yJUgF36YsZ81cOyxT0QxmXD2EQpapAouzWVA== + +eventsource@^3.0.2: + version "3.0.6" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-3.0.6.tgz#5c4b24cd70c0323eed2651a5ee07bd4bc391e656" + integrity sha512-l19WpE2m9hSuyP06+FbuUUf1G+R0SFLrtQfbRb9PRr+oimOfxQhgGCbVaXg5IvZyyTThJsxh6L/srkMiCeBPDA== + dependencies: + eventsource-parser "^3.0.1" + execa@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/execa/-/execa-8.0.1.tgz#51f6a5943b580f963c3ca9c6321796db8cc39b8c" @@ -3931,7 +3969,12 @@ express-basic-auth@1.2.1: dependencies: basic-auth "^2.0.1" -express@5.1.0: +express-rate-limit@^7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-7.5.0.tgz#6a67990a724b4fbbc69119419feef50c51e8b28f" + integrity sha512-eB5zbQh5h+VenMPM3fh+nw1YExi5nMr6HUCR62ELSP11huvxm/Uir1H1QEyTkk5QX6A58pX6NmaTMceKZ0Eodg== + +express@5.1.0, express@^5.0.1: version "5.1.0" resolved "https://registry.yarnpkg.com/express/-/express-5.1.0.tgz#d31beaf715a0016f0d53f47d3b4d7acf28c75cc9" integrity sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA== @@ -4025,12 +4068,12 @@ fast-xml-parser@4.4.1: dependencies: strnum "^1.0.5" -fast-xml-parser@5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.2.1.tgz#d6a4f9eac066dc0987bbcfe4ca050ef8f7f67137" - integrity sha512-Kqq/ewnRACQ20e0BlQ5KqHRYWRBp7yv+jttK4Yj2yY+2ldgCoxJkrP1NHUhjypsJ+eQXlGJ/jebM3wa60s1rbQ== +fast-xml-parser@5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/fast-xml-parser/-/fast-xml-parser-5.2.2.tgz#dda87446b623d812908a1efc5f3f8245a8f6a64b" + integrity sha512-ZaCmslH75Jkfowo/x44Uq8KT5SutC5BFxHmY61nmTXPccw11PVuIXKUqC2hembMkJ3nPwTkQESXiUlsKutCbMg== dependencies: - strnum "^2.0.5" + strnum "^2.1.0" fastest-levenshtein@^1.0.7: version "1.0.16" @@ -5060,10 +5103,10 @@ lilconfig@^3.1.3: resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-3.1.3.tgz#a1bcfd6257f9585bf5ae14ceeebb7b559025e4c4" integrity sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw== -lint-staged@15.5.1: - version "15.5.1" - resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.5.1.tgz#6de35298964641b8b6e060d3db0fb6ac866c6e24" - integrity sha512-6m7u8mue4Xn6wK6gZvSCQwBvMBR36xfY24nF5bMTf2MHDYG6S3yhJuOgdYVw99hsjyDt2d4z168b3naI8+NWtQ== +lint-staged@15.5.2: + version "15.5.2" + resolved "https://registry.yarnpkg.com/lint-staged/-/lint-staged-15.5.2.tgz#beff028fd0681f7db26ffbb67050a21ed4d059a3" + integrity sha512-YUSOLq9VeRNAo/CTaVmhGDKG+LBtA8KF1X4K5+ykMSwWST1vDxJRB2kv2COgLb1fvpCo+A/y9A0G0znNVmdx4w== dependencies: chalk "^5.4.1" commander "^13.1.0" @@ -5457,6 +5500,11 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +object-assign@^4: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-inspect@^1.13.3: version "1.13.4" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.4.tgz#8375265e21bc20d0fa582c22e1b13485d6e00213" @@ -5786,6 +5834,11 @@ pidusage@~3.0: dependencies: safe-buffer "^5.2.1" +pkce-challenge@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkce-challenge/-/pkce-challenge-5.0.0.tgz#c3a405cb49e272094a38e890a2b51da0228c4d97" + integrity sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ== + pm2-axon-rpc@~0.7.0, pm2-axon-rpc@~0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz#2daec5383a63135b3f18babb70266dacdcbc429a" @@ -6740,7 +6793,7 @@ strnum@^1.0.5: resolved "https://registry.yarnpkg.com/strnum/-/strnum-1.1.2.tgz#57bca4fbaa6f271081715dbc9ed7cee5493e28e4" integrity sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA== -strnum@^2.0.5: +strnum@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strnum/-/strnum-2.1.0.tgz#12c2c6de59d3820a8128b486c9c106c1bf6c4924" integrity sha512-w0S//9BqZZGw0L0Y8uLSelFGnDJgTyyNQLmSlPnVz43zPAiqu3w4t8J8sDqqANOGeZIZ/9jWuPguYcEnsoHv4A== @@ -7107,19 +7160,19 @@ validate-npm-package-name@^5.0.1: resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz#a316573e9b49f3ccd90dbb6eb52b3f06c6d604e8" integrity sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ== -vary@^1.1.2: +vary@^1, vary@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== -vite-node@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-3.1.2.tgz#b17869a12307f5260b20ba4b58cf493afee70aa7" - integrity sha512-/8iMryv46J3aK13iUXsei5G/A3CUlW4665THCPS+K8xAaqrVWiGB4RfXMQXCLjpK9P2eK//BczrVkn5JLAk6DA== +vite-node@3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vite-node/-/vite-node-3.1.3.tgz#d021ced40b5a057305eaea9ce62c610c33b60a48" + integrity sha512-uHV4plJ2IxCl4u1up1FQRrqclylKAogbtBfOTwcuJ28xFi+89PZ57BRh+naIRvH70HPwxy5QHYzg1OrEaC7AbA== dependencies: cac "^6.7.14" debug "^4.4.0" - es-module-lexer "^1.6.0" + es-module-lexer "^1.7.0" pathe "^2.0.3" vite "^5.0.0 || ^6.0.0" @@ -7144,18 +7197,18 @@ vitest-mock-express@2.2.0: dependencies: "@types/express" "^4.17.21" -vitest@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/vitest/-/vitest-3.1.2.tgz#63afc16b6da3bea6e39f5387d80719e70634ba66" - integrity sha512-WaxpJe092ID1C0mr+LH9MmNrhfzi8I65EX/NRU/Ld016KqQNRgxSOlGNP1hHN+a/F8L15Mh8klwaF77zR3GeDQ== - dependencies: - "@vitest/expect" "3.1.2" - "@vitest/mocker" "3.1.2" - "@vitest/pretty-format" "^3.1.2" - "@vitest/runner" "3.1.2" - "@vitest/snapshot" "3.1.2" - "@vitest/spy" "3.1.2" - "@vitest/utils" "3.1.2" +vitest@3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/vitest/-/vitest-3.1.3.tgz#0b0b01932408cd3af61867f4468d28bd83406ffb" + integrity sha512-188iM4hAHQ0km23TN/adso1q5hhwKqUpv+Sd6p5sOuh6FhQnRNW3IsiIpvxqahtBabsJ2SLZgmGSpcYK4wQYJw== + dependencies: + "@vitest/expect" "3.1.3" + "@vitest/mocker" "3.1.3" + "@vitest/pretty-format" "^3.1.3" + "@vitest/runner" "3.1.3" + "@vitest/snapshot" "3.1.3" + "@vitest/spy" "3.1.3" + "@vitest/utils" "3.1.3" chai "^5.2.0" debug "^4.4.0" expect-type "^1.2.1" @@ -7168,7 +7221,7 @@ vitest@3.1.2: tinypool "^1.0.2" tinyrainbow "^2.0.0" vite "^5.0.0 || ^6.0.0" - vite-node "3.1.2" + vite-node "3.1.3" why-is-node-running "^2.3.0" vizion@~2.2.1: @@ -7446,3 +7499,13 @@ yoctocolors-cjs@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz#f4b905a840a37506813a7acaa28febe97767a242" integrity sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA== + +zod-to-json-schema@^3.24.1: + version "3.24.5" + resolved "https://registry.yarnpkg.com/zod-to-json-schema/-/zod-to-json-schema-3.24.5.tgz#d1095440b147fb7c2093812a53c54df8d5df50a3" + integrity sha512-/AuWwMP+YqiPbsJx5D6TfgRTc4kTLjsh5SOcd4bLsfUg2RcEXrFMJl1DGgdHy2aCfsIA/cr/1JM0xcB2GZji8g== + +zod@^3.23.8, zod@^3.24.2: + version "3.24.4" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.4.tgz#e2e2cca5faaa012d76e527d0d36622e0a90c315f" + integrity sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg==