diff --git a/package.json b/package.json index b613d83..a1ffb1d 100644 --- a/package.json +++ b/package.json @@ -7,5 +7,8 @@ "author": "", "license": "UNLICENSED", "packageManager": "pnpm@10.20.0", - "type": "module" + "type": "module", + "devDependencies": { + "tsoa": "^6.6.0" + } } diff --git a/packages/api/.gitignore b/packages/api/.gitignore new file mode 100644 index 0000000..9ab870d --- /dev/null +++ b/packages/api/.gitignore @@ -0,0 +1 @@ +generated/ diff --git a/packages/api/package.json b/packages/api/package.json index 0a752bd..bb75428 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -14,6 +14,7 @@ "typescript": "~5.9.3" }, "dependencies": { + "@tsoa/runtime": "^6.6.0", "express": "^5.1.0" } } diff --git a/packages/api/src/controllers/healthCheckController.ts b/packages/api/src/controllers/healthCheckController.ts new file mode 100644 index 0000000..d45d21d --- /dev/null +++ b/packages/api/src/controllers/healthCheckController.ts @@ -0,0 +1,20 @@ +import { Controller, Get, Route, SuccessResponse } from 'tsoa'; + +export interface User { + email: string; + name: string; + phoneNumbers: string[]; +} + +export type UserCreationParams = Pick; + +@Route('health') +export class HealthCheckController extends Controller { + @Get('ok') + @SuccessResponse('200', 'OK') + public async getOk( + ): Promise { + this.setStatus(200); + return 'Ok'; + } +} diff --git a/packages/api/src/index.ts b/packages/api/src/index.ts index 05632bd..0840c4d 100644 --- a/packages/api/src/index.ts +++ b/packages/api/src/index.ts @@ -1,11 +1,13 @@ import express from 'express'; +import { RegisterRoutes } from './generated/routes.js'; const app = express(); const port = 3000; -app.get('/', (_, res) => { - res.send('Hello World!'); -}); +app.use(express.urlencoded({ extended: true })); +app.use(express.json()); + +RegisterRoutes(app); app.listen(port, () => { console.log(`Server is running at http://localhost:${port}`); diff --git a/packages/api/src/middleware/authentication.ts b/packages/api/src/middleware/authentication.ts new file mode 100644 index 0000000..63c24b2 --- /dev/null +++ b/packages/api/src/middleware/authentication.ts @@ -0,0 +1,10 @@ +import * as express from 'express'; + +export async function expressAuthentication( + request: express.Request, + securityName: string, + scopes?: string[] +): Promise { + console.dir({ request, securityName, scopes }); + return {}; +} diff --git a/packages/api/tsconfig.json b/packages/api/tsconfig.json index d35fa21..d484179 100644 --- a/packages/api/tsconfig.json +++ b/packages/api/tsconfig.json @@ -40,6 +40,21 @@ "noUncheckedSideEffectImports": true, "moduleDetection": "force", "skipLibCheck": true, + + // Custom Options + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "useDefineForClassFields": false, + "moduleResolution": "nodenext", + "incremental": true, + "noImplicitAny": true, + "strictNullChecks": true, + "strictFunctionTypes": true, + "strictBindCallApply": true, + "strictPropertyInitialization": true, + "noImplicitThis": true, + "alwaysStrict": true, + "forceConsistentCasingInFileNames": true, }, - "files": ["./src/index.ts"], + "files": ["./src/index.ts"] } diff --git a/packages/frontend/.gitignore b/packages/frontend/.gitignore index b1d225e..df7fb2a 100644 --- a/packages/frontend/.gitignore +++ b/packages/frontend/.gitignore @@ -41,3 +41,6 @@ __screenshots__/ # System files .DS_Store Thumbs.db + +### +src/generated-api/ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a5fa007..2d4f346 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -6,10 +6,17 @@ settings: importers: - .: {} + .: + devDependencies: + tsoa: + specifier: ^6.6.0 + version: 6.6.0 packages/api: dependencies: + '@tsoa/runtime': + specifier: ^6.6.0 + version: 6.6.0 express: specifier: ^5.1.0 version: 5.1.0 @@ -56,7 +63,7 @@ importers: devDependencies: '@angular/build': specifier: ^20.3.8 - version: 20.3.8(@angular/compiler-cli@20.3.9(@angular/compiler@20.3.9)(typescript@5.9.3))(@angular/compiler@20.3.9)(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.9(@angular/common@20.3.9(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(karma@6.4.4)(postcss@8.5.6)(tslib@2.8.1)(typescript@5.9.3) + version: 20.3.8(@angular/compiler-cli@20.3.9(@angular/compiler@20.3.9)(typescript@5.9.3))(@angular/compiler@20.3.9)(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.9(@angular/common@20.3.9(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(karma@6.4.4)(postcss@8.5.6)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.8.1) '@angular/cli': specifier: ^20.3.8 version: 20.3.8(@types/node@24.9.2)(chokidar@4.0.3) @@ -521,6 +528,97 @@ packages: cpu: [x64] os: [win32] + '@hapi/accept@6.0.3': + resolution: {integrity: sha512-p72f9k56EuF0n3MwlBNThyVE5PXX40g+aQh+C/xbKrfzahM2Oispv3AXmOIU51t3j77zay1qrX7IIziZXspMlw==} + + '@hapi/ammo@6.0.1': + resolution: {integrity: sha512-pmL+nPod4g58kXrMcsGLp05O2jF4P2Q3GiL8qYV7nKYEh3cGf+rV4P5Jyi2Uq0agGhVU63GtaSAfBEZOlrJn9w==} + + '@hapi/b64@6.0.1': + resolution: {integrity: sha512-ZvjX4JQReUmBheeCq+S9YavcnMMHWqx3S0jHNXWIM1kQDxB9cyfSycpVvjfrKcIS8Mh5N3hmu/YKo4Iag9g2Kw==} + + '@hapi/boom@10.0.1': + resolution: {integrity: sha512-ERcCZaEjdH3OgSJlyjVk8pHIFeus91CjKP3v+MpgBNp5IvGzP2l/bRiD78nqYcKPaZdbKkK5vDBVPd2ohHBlsA==} + + '@hapi/bounce@3.0.2': + resolution: {integrity: sha512-d0XmlTi3H9HFDHhQLjg4F4auL1EY3Wqj7j7/hGDhFFe6xAbnm3qiGrXeT93zZnPH8gH+SKAFYiRzu26xkXcH3g==} + + '@hapi/bourne@3.0.0': + resolution: {integrity: sha512-Waj1cwPXJDucOib4a3bAISsKJVb15MKi9IvmTI/7ssVEm6sywXGjVJDhl6/umt1pK1ZS7PacXU3A1PmFKHEZ2w==} + + '@hapi/call@9.0.1': + resolution: {integrity: sha512-uPojQRqEL1GRZR4xXPqcLMujQGaEpyVPRyBlD8Pp5rqgIwLhtveF9PkixiKru2THXvuN8mUrLeet5fqxKAAMGg==} + + '@hapi/catbox-memory@6.0.2': + resolution: {integrity: sha512-H1l4ugoFW/ZRkqeFrIo8p1rWN0PA4MDTfu4JmcoNDvnY975o29mqoZblqFTotxNHlEkMPpIiIBJTV+Mbi+aF0g==} + + '@hapi/catbox@12.1.1': + resolution: {integrity: sha512-hDqYB1J+R0HtZg4iPH3LEnldoaBsar6bYp0EonBmNQ9t5CO+1CqgCul2ZtFveW1ReA5SQuze9GPSU7/aecERhw==} + + '@hapi/content@6.0.0': + resolution: {integrity: sha512-CEhs7j+H0iQffKfe5Htdak5LBOz/Qc8TRh51cF+BFv0qnuph3Em4pjGVzJMkI2gfTDdlJKWJISGWS1rK34POGA==} + + '@hapi/cryptiles@6.0.1': + resolution: {integrity: sha512-9GM9ECEHfR8lk5ASOKG4+4ZsEzFqLfhiryIJ2ISePVB92OHLp/yne4m+zn7z9dgvM98TLpiFebjDFQ0UHcqxXQ==} + engines: {node: '>=14.0.0'} + + '@hapi/file@3.0.0': + resolution: {integrity: sha512-w+lKW+yRrLhJu620jT3y+5g2mHqnKfepreykvdOcl9/6up8GrQQn+l3FRTsjHTKbkbfQFkuksHpdv2EcpKcJ4Q==} + + '@hapi/hapi@21.4.3': + resolution: {integrity: sha512-Q7g0ZY4gxU69wabFKH75qR0AFOdiOECj6vGqTHBSO5Lrwe6TwD8r9LkYQIbvtG8N423VDpdVsiZP8MnBwmD6Hw==} + engines: {node: '>=14.15.0'} + + '@hapi/heavy@8.0.1': + resolution: {integrity: sha512-gBD/NANosNCOp6RsYTsjo2vhr5eYA3BEuogk6cxY0QdhllkkTaJFYtTXv46xd6qhBVMbMMqcSdtqey+UQU3//w==} + + '@hapi/hoek@11.0.7': + resolution: {integrity: sha512-HV5undWkKzcB4RZUusqOpcgxOaq6VOAH7zhhIr2g3G8NF/MlFO75SjOr2NfuSx0Mh40+1FqCkagKLJRykUWoFQ==} + + '@hapi/iron@7.0.1': + resolution: {integrity: sha512-tEZnrOujKpS6jLKliyWBl3A9PaE+ppuL/+gkbyPPDb/l2KSKQyH4lhMkVb+sBhwN+qaxxlig01JRqB8dk/mPxQ==} + + '@hapi/mimos@7.0.1': + resolution: {integrity: sha512-b79V+BrG0gJ9zcRx1VGcCI6r6GEzzZUgiGEJVoq5gwzuB2Ig9Cax8dUuBauQCFKvl2YWSWyOc8mZ8HDaJOtkew==} + + '@hapi/nigel@5.0.1': + resolution: {integrity: sha512-uv3dtYuB4IsNaha+tigWmN8mQw/O9Qzl5U26Gm4ZcJVtDdB1AVJOwX3X5wOX+A07qzpEZnOMBAm8jjSqGsU6Nw==} + engines: {node: '>=14.0.0'} + + '@hapi/pez@6.1.0': + resolution: {integrity: sha512-+FE3sFPYuXCpuVeHQ/Qag1b45clR2o54QoonE/gKHv9gukxQ8oJJZPR7o3/ydDTK6racnCJXxOyT1T93FCJMIg==} + + '@hapi/podium@5.0.2': + resolution: {integrity: sha512-T7gf2JYHQQfEfewTQFbsaXoZxSvuXO/QBIGljucUQ/lmPnTTNAepoIKOakWNVWvo2fMEDjycu77r8k6dhreqHA==} + + '@hapi/shot@6.0.2': + resolution: {integrity: sha512-WKK1ShfJTrL1oXC0skoIZQYzvLsyMDEF8lfcWuQBjpjCN29qivr9U36ld1z0nt6edvzv28etNMOqUF4klnHryw==} + + '@hapi/somever@4.1.1': + resolution: {integrity: sha512-lt3QQiDDOVRatS0ionFDNrDIv4eXz58IibQaZQDOg4DqqdNme8oa0iPWcE0+hkq/KTeBCPtEOjDOBKBKwDumVg==} + + '@hapi/statehood@8.2.0': + resolution: {integrity: sha512-63JlCVIrsmuunWsyc3OeuFO+gH6v56swLCl7OM1w09l/exQKPUxSUDF2Slkuw8k91nIzr0A2/aPvjLOWf9ksrg==} + + '@hapi/subtext@8.1.1': + resolution: {integrity: sha512-ex1Y2s/KuJktS8Ww0k6XJ5ysSKrzNym4i5pDVuCwlSgHHviHUsT1JNzE6FYhNU9TTHSNdyfue/t2m89bpkX9Jw==} + + '@hapi/teamwork@6.0.1': + resolution: {integrity: sha512-52OXRslUfYwXAOG8k58f2h2ngXYQGP0x5RPOo+eWA/FtyLgHjGMrE3+e9LSXP/0q2YfHAK5wj9aA9DTy1K+kyQ==} + engines: {node: '>=14.0.0'} + + '@hapi/topo@6.0.2': + resolution: {integrity: sha512-KR3rD5inZbGMrHmgPxsJ9dbi6zEK+C3ZwUwTa+eMwWLz7oijWUTWD2pMSNNYJAU6Qq+65NkxXjqHr/7LM2Xkqg==} + + '@hapi/validate@2.0.1': + resolution: {integrity: sha512-NZmXRnrSLK8MQ9y/CMqE9WSspgB9xA41/LlYR0k967aSZebWr4yNrpxIbov12ICwKy4APSlWXZga9jN5p6puPA==} + + '@hapi/vise@5.0.1': + resolution: {integrity: sha512-XZYWzzRtINQLedPYlIkSkUr7m5Ddwlu99V9elh8CSygXstfv3UnWIXT0QD+wmR0VAG34d2Vx3olqcEhRRoTu9A==} + + '@hapi/wreck@18.1.0': + resolution: {integrity: sha512-0z6ZRCmFEfV/MQqkQomJ7sl/hyxvcZM7LtuVqN3vdAO4vM9eBbowl0kaqQj9EJJQab+3Uuh1GxbGIBFy4NfJ4w==} + '@inquirer/ansi@1.0.1': resolution: {integrity: sha512-yqq0aJW/5XPhi5xOAL1xRCpe1eh8UFVgYFpFsjEqmIR8rKLyP+HINvFXwUaxYICflJrVlxnp7lLN6As735kVpw==} engines: {node: '>=18'} @@ -1146,6 +1244,15 @@ packages: '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@tsoa/cli@6.6.0': + resolution: {integrity: sha512-thSW0EiqjkF7HspcPIVIy0ZX65VqbWALHbxwl8Sk83j2kakOMq+fJvfo8FcBAWlMki+JDH7CO5iaAaSLHbeqtg==} + engines: {node: '>=18.0.0', yarn: '>=1.9.4'} + hasBin: true + + '@tsoa/runtime@6.6.0': + resolution: {integrity: sha512-+rF2gdL8CX+jQ82/IBc+MRJFNAvWPoBBl77HHJv3ESVMqbKhlhlo97JHmKyFbLcX6XOJN8zl8gfQpAEJN4SOMQ==} + engines: {node: '>=18.0.0', yarn: '>=1.9.4'} + '@tufjs/canonical-json@2.0.0': resolution: {integrity: sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==} engines: {node: ^16.14.0 || >=18.0.0} @@ -1154,12 +1261,21 @@ packages: resolution: {integrity: sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==} engines: {node: ^18.17.0 || >=20.5.0} + '@types/accepts@1.3.7': + resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} + '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/content-disposition@0.5.9': + resolution: {integrity: sha512-8uYXI3Gw35MhiVYhG3s295oihrxRyytcRHjSjqnqZVDDy/xcGBRny7+Xj1Wgfhv5QzRtN2hB2dVRBUX9XW3UcQ==} + + '@types/cookies@0.9.2': + resolution: {integrity: sha512-1AvkDdZM2dbyFybL4fxpuNCaWyv//0AwsuUk2DWeXyM1/5ZKm6W3z6mQi24RZ4l2ucY+bkSHzbDVpySqPGuV8A==} + '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} @@ -1172,15 +1288,30 @@ packages: '@types/express@5.0.5': resolution: {integrity: sha512-LuIQOcb6UmnF7C1PCFmEU1u2hmiHL43fgFQX67sN3H4Z+0Yk0Neo++mFsBjhOAuLzvlQeqAAkeDOZrJs9rzumQ==} + '@types/http-assert@1.5.6': + resolution: {integrity: sha512-TTEwmtjgVbYAzZYWyeHPrrtWnfVkm8tQkP8P21uQifPgMRgjrow3XDEYqucuC8SKZJT7pUnhU/JymvjggxO9vw==} + '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} '@types/jasmine@5.1.12': resolution: {integrity: sha512-1BzPxNsFDLDfj9InVR3IeY0ZVf4o9XV+4mDqoCfyPkbsA7dYyKAPAb2co6wLFlHcvxPlt1wShm7zQdV7uTfLGA==} + '@types/keygrip@1.0.6': + resolution: {integrity: sha512-lZuNAY9xeJt7Bx4t4dx0rYCDqGPW8RXhQZK1td7d4H6E9zYbLoOtjBvfwdTKpsyxQI/2jv+armjX/RW+ZNpXOQ==} + + '@types/koa-compose@3.2.9': + resolution: {integrity: sha512-BroAZ9FTvPiCy0Pi8tjD1OfJ7bgU1gQf0eR6e1Vm+JJATy9eKOG3hQMFtMciMawiSOVnLMdmUOC46s7HBhSTsA==} + + '@types/koa@2.15.0': + resolution: {integrity: sha512-7QFsywoE5URbuVnG3loe03QXuGajrnotr3gQkXcEBShORai23MePfFYdhz90FEtBBpkyIYQbVD+evKtloCgX3g==} + '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} + '@types/multer@1.4.13': + resolution: {integrity: sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw==} + '@types/node@24.9.2': resolution: {integrity: sha512-uWN8YqxXxqFMX2RqGOrumsKeti4LlmIMIyV0lgut4jx7KQBcBiW6vkDtIBvHnHIquwNfJhk8v2OtmO8zXWHfPA==} @@ -1266,6 +1397,9 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} + array-flatten@1.1.1: + resolution: {integrity: sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==} + balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} @@ -1375,6 +1509,10 @@ packages: cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} + cliui@8.0.1: + resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} + engines: {node: '>=12'} + cliui@9.0.1: resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} engines: {node: '>=20'} @@ -1396,6 +1534,10 @@ packages: resolution: {integrity: sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==} engines: {node: '>= 0.10.0'} + content-disposition@0.5.4: + resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} + engines: {node: '>= 0.6'} + content-disposition@1.0.0: resolution: {integrity: sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==} engines: {node: '>= 0.6'} @@ -1410,10 +1552,17 @@ packages: convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.0.6: + resolution: {integrity: sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==} + cookie-signature@1.2.2: resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} engines: {node: '>=6.6.0'} + cookie@0.7.1: + resolution: {integrity: sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==} + engines: {node: '>= 0.6'} + cookie@0.7.2: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} @@ -1617,6 +1766,10 @@ packages: peerDependencies: express: '>= 4.11' + express@4.21.2: + resolution: {integrity: sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==} + engines: {node: '>= 0.10.0'} + express@5.1.0: resolution: {integrity: sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==} engines: {node: '>= 18'} @@ -1650,6 +1803,10 @@ packages: resolution: {integrity: sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==} engines: {node: '>= 0.8'} + finalhandler@1.3.1: + resolution: {integrity: sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==} + engines: {node: '>= 0.8'} + finalhandler@2.1.0: resolution: {integrity: sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==} engines: {node: '>= 0.8'} @@ -1674,10 +1831,18 @@ packages: resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} engines: {node: '>= 0.6'} + fresh@0.5.2: + resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} + engines: {node: '>= 0.6'} + fresh@2.0.0: resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} engines: {node: '>= 0.8'} + fs-extra@11.3.2: + resolution: {integrity: sha512-Xr9F6z6up6Ws+NjzMCZc6WXg2YFRlrLP9NQDO3VQrWrfiojdhS56TzueT88ze0uBdCTwEIhQ3ptnmKeWGFAe0A==} + engines: {node: '>=14.14'} + fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -1743,6 +1908,11 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + handlebars@4.7.8: + resolution: {integrity: sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==} + engines: {node: '>=0.4.7'} + hasBin: true + has-flag@4.0.0: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} @@ -1885,6 +2055,10 @@ packages: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} + is-what@4.1.16: + resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==} + engines: {node: '>=12.13'} + isbinaryfile@4.0.10: resolution: {integrity: sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==} engines: {node: '>= 8.0.0'} @@ -1958,6 +2132,9 @@ packages: jsonfile@4.0.0: resolution: {integrity: sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==} + jsonfile@6.2.0: + resolution: {integrity: sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg==} + jsonparse@1.3.1: resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} engines: {'0': node >= 0.2.0} @@ -2043,10 +2220,21 @@ packages: resolution: {integrity: sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==} engines: {node: '>= 0.8'} + merge-anything@5.1.7: + resolution: {integrity: sha512-eRtbOb1N5iyH0tkQDAoQ4Ipsp/5qSR79Dzrz8hEPxRX10RWWR/iQXdoKmBSRCThY1Fh5EhISDtpSc93fpxUniQ==} + engines: {node: '>=12.13'} + + merge-descriptors@1.0.3: + resolution: {integrity: sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==} + merge-descriptors@2.0.0: resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} engines: {node: '>=18'} + methods@1.1.2: + resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} + engines: {node: '>= 0.6'} + micromatch@4.0.8: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} @@ -2067,6 +2255,11 @@ packages: resolution: {integrity: sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==} engines: {node: '>= 0.6'} + mime@1.6.0: + resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} + engines: {node: '>=4'} + hasBin: true + mime@2.6.0: resolution: {integrity: sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==} engines: {node: '>=4.0.0'} @@ -2173,6 +2366,9 @@ packages: resolution: {integrity: sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==} engines: {node: '>= 0.6'} + neo-async@2.6.2: + resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} + node-addon-api@6.1.0: resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==} @@ -2305,6 +2501,9 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} + path-to-regexp@0.1.12: + resolution: {integrity: sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==} + path-to-regexp@8.3.0: resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} @@ -2465,10 +2664,18 @@ packages: engines: {node: '>=10'} hasBin: true + send@0.19.0: + resolution: {integrity: sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==} + engines: {node: '>= 0.8.0'} + send@1.2.0: resolution: {integrity: sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==} engines: {node: '>= 18'} + serve-static@1.16.2: + resolution: {integrity: sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==} + engines: {node: '>= 0.8.0'} + serve-static@2.2.0: resolution: {integrity: sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==} engines: {node: '>= 18'} @@ -2646,9 +2853,18 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + ts-deepmerge@7.0.3: + resolution: {integrity: sha512-Du/ZW2RfwV/D4cmA5rXafYjBQVuvu4qGiEEla4EmEHVHgRdx68Gftx7i66jn2bzHPwSVZY36Ae6OuDn9el4ZKA==} + engines: {node: '>=14.13.1'} + tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsoa@6.6.0: + resolution: {integrity: sha512-7FudRojmbEpbSQ3t1pyG5EjV3scF7/X75giQt1q+tnuGjjJppB8BOEmIdCK/G8S5Dqnmpwz5Q3vxluKozpIW9A==} + engines: {node: '>=18.0.0', yarn: '>=1.9.4'} + hasBin: true + tuf-js@3.1.0: resolution: {integrity: sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==} engines: {node: ^18.17.0 || >=20.5.0} @@ -2670,6 +2886,11 @@ packages: resolution: {integrity: sha512-O3oYyCMPYgNNHuO7Jjk3uacJWZF8loBgwrfd/5LE/HyZ3lUIOdniQ7DNXJcIgZbwioZxk0fLfI4EVnetdiX5jg==} hasBin: true + uglify-js@3.19.3: + resolution: {integrity: sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==} + engines: {node: '>=0.8.0'} + hasBin: true + undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} @@ -2685,6 +2906,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + universalify@2.0.1: + resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} + engines: {node: '>= 10.0.0'} + unpipe@1.0.0: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} @@ -2709,6 +2934,10 @@ packages: resolution: {integrity: sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==} engines: {node: ^18.17.0 || >=20.5.0} + validator@13.15.20: + resolution: {integrity: sha512-KxPOq3V2LmfQPP4eqf3Mq/zrT0Dqp2Vmx2Bn285LwVahLc+CsxOM0crBHczm8ijlcjZ0Q5Xd6LW3z3odTPnlrw==} + engines: {node: '>= 0.10'} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -2778,6 +3007,9 @@ packages: engines: {node: ^18.17.0 || >=20.5.0} hasBin: true + wordwrap@1.0.0: + resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -2823,10 +3055,19 @@ packages: resolution: {integrity: sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==} engines: {node: '>=18'} + yaml@2.8.1: + resolution: {integrity: sha512-lcYcMxX2PO9XMGvAJkJ3OsNMw+/7FKes7/hgerGUYWIoWu5j/+YQqcZr5JnPZWzOsEBgMbSbiSTn/dv/69Mkpw==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} + yargs-parser@21.1.1: + resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} + engines: {node: '>=12'} + yargs-parser@22.0.0: resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} @@ -2835,6 +3076,10 @@ packages: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} + yargs@17.7.2: + resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} + engines: {node: '>=12'} + yargs@18.0.0: resolution: {integrity: sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==} engines: {node: ^20.19.0 || ^22.12.0 || >=23} @@ -2973,7 +3218,7 @@ snapshots: transitivePeerDependencies: - chokidar - '@angular/build@20.3.8(@angular/compiler-cli@20.3.9(@angular/compiler@20.3.9)(typescript@5.9.3))(@angular/compiler@20.3.9)(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.9(@angular/common@20.3.9(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(karma@6.4.4)(postcss@8.5.6)(tslib@2.8.1)(typescript@5.9.3)': + '@angular/build@20.3.8(@angular/compiler-cli@20.3.9(@angular/compiler@20.3.9)(typescript@5.9.3))(@angular/compiler@20.3.9)(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(@angular/platform-browser@20.3.9(@angular/common@20.3.9(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1))(rxjs@7.8.2))(@angular/core@20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1)))(@types/node@24.9.2)(chokidar@4.0.3)(karma@6.4.4)(postcss@8.5.6)(tslib@2.8.1)(typescript@5.9.3)(yaml@2.8.1)': dependencies: '@ampproject/remapping': 2.3.0 '@angular-devkit/architect': 0.2003.8(chokidar@4.0.3) @@ -2983,7 +3228,7 @@ snapshots: '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-split-export-declaration': 7.24.7 '@inquirer/confirm': 5.1.14(@types/node@24.9.2) - '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@24.9.2)(sass@1.90.0)) + '@vitejs/plugin-basic-ssl': 2.1.0(vite@7.1.11(@types/node@24.9.2)(sass@1.90.0)(yaml@2.8.1)) beasties: 0.3.5 browserslist: 4.27.0 esbuild: 0.25.9 @@ -3003,7 +3248,7 @@ snapshots: tinyglobby: 0.2.14 tslib: 2.8.1 typescript: 5.9.3 - vite: 7.1.11(@types/node@24.9.2)(sass@1.90.0) + vite: 7.1.11(@types/node@24.9.2)(sass@1.90.0)(yaml@2.8.1) watchpack: 2.4.4 optionalDependencies: '@angular/core': 20.3.9(@angular/compiler@20.3.9)(rxjs@7.8.2)(zone.js@0.15.1) @@ -3322,6 +3567,169 @@ snapshots: '@esbuild/win32-x64@0.25.9': optional: true + '@hapi/accept@6.0.3': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hoek': 11.0.7 + + '@hapi/ammo@6.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/b64@6.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/boom@10.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/bounce@3.0.2': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hoek': 11.0.7 + + '@hapi/bourne@3.0.0': {} + + '@hapi/call@9.0.1': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hoek': 11.0.7 + + '@hapi/catbox-memory@6.0.2': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hoek': 11.0.7 + + '@hapi/catbox@12.1.1': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hoek': 11.0.7 + '@hapi/podium': 5.0.2 + '@hapi/validate': 2.0.1 + + '@hapi/content@6.0.0': + dependencies: + '@hapi/boom': 10.0.1 + + '@hapi/cryptiles@6.0.1': + dependencies: + '@hapi/boom': 10.0.1 + + '@hapi/file@3.0.0': {} + + '@hapi/hapi@21.4.3': + dependencies: + '@hapi/accept': 6.0.3 + '@hapi/ammo': 6.0.1 + '@hapi/boom': 10.0.1 + '@hapi/bounce': 3.0.2 + '@hapi/call': 9.0.1 + '@hapi/catbox': 12.1.1 + '@hapi/catbox-memory': 6.0.2 + '@hapi/heavy': 8.0.1 + '@hapi/hoek': 11.0.7 + '@hapi/mimos': 7.0.1 + '@hapi/podium': 5.0.2 + '@hapi/shot': 6.0.2 + '@hapi/somever': 4.1.1 + '@hapi/statehood': 8.2.0 + '@hapi/subtext': 8.1.1 + '@hapi/teamwork': 6.0.1 + '@hapi/topo': 6.0.2 + '@hapi/validate': 2.0.1 + + '@hapi/heavy@8.0.1': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hoek': 11.0.7 + '@hapi/validate': 2.0.1 + + '@hapi/hoek@11.0.7': {} + + '@hapi/iron@7.0.1': + dependencies: + '@hapi/b64': 6.0.1 + '@hapi/boom': 10.0.1 + '@hapi/bourne': 3.0.0 + '@hapi/cryptiles': 6.0.1 + '@hapi/hoek': 11.0.7 + + '@hapi/mimos@7.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + mime-db: 1.54.0 + + '@hapi/nigel@5.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + '@hapi/vise': 5.0.1 + + '@hapi/pez@6.1.0': + dependencies: + '@hapi/b64': 6.0.1 + '@hapi/boom': 10.0.1 + '@hapi/content': 6.0.0 + '@hapi/hoek': 11.0.7 + '@hapi/nigel': 5.0.1 + + '@hapi/podium@5.0.2': + dependencies: + '@hapi/hoek': 11.0.7 + '@hapi/teamwork': 6.0.1 + '@hapi/validate': 2.0.1 + + '@hapi/shot@6.0.2': + dependencies: + '@hapi/hoek': 11.0.7 + '@hapi/validate': 2.0.1 + + '@hapi/somever@4.1.1': + dependencies: + '@hapi/bounce': 3.0.2 + '@hapi/hoek': 11.0.7 + + '@hapi/statehood@8.2.0': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/bounce': 3.0.2 + '@hapi/bourne': 3.0.0 + '@hapi/cryptiles': 6.0.1 + '@hapi/hoek': 11.0.7 + '@hapi/iron': 7.0.1 + '@hapi/validate': 2.0.1 + + '@hapi/subtext@8.1.1': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/bourne': 3.0.0 + '@hapi/content': 6.0.0 + '@hapi/file': 3.0.0 + '@hapi/hoek': 11.0.7 + '@hapi/pez': 6.1.0 + '@hapi/wreck': 18.1.0 + + '@hapi/teamwork@6.0.1': {} + + '@hapi/topo@6.0.2': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/validate@2.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + '@hapi/topo': 6.0.2 + + '@hapi/vise@5.0.1': + dependencies: + '@hapi/hoek': 11.0.7 + + '@hapi/wreck@18.1.0': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/bourne': 3.0.0 + '@hapi/hoek': 11.0.7 + '@inquirer/ansi@1.0.1': {} '@inquirer/checkbox@4.3.0(@types/node@24.9.2)': @@ -3861,6 +4269,35 @@ snapshots: '@socket.io/component-emitter@3.1.2': {} + '@tsoa/cli@6.6.0': + dependencies: + '@tsoa/runtime': 6.6.0 + '@types/multer': 1.4.13 + fs-extra: 11.3.2 + glob: 10.4.5 + handlebars: 4.7.8 + merge-anything: 5.1.7 + minimatch: 9.0.5 + ts-deepmerge: 7.0.3 + typescript: 5.9.3 + validator: 13.15.20 + yaml: 2.8.1 + yargs: 17.7.2 + transitivePeerDependencies: + - supports-color + + '@tsoa/runtime@6.6.0': + dependencies: + '@hapi/boom': 10.0.1 + '@hapi/hapi': 21.4.3 + '@types/koa': 2.15.0 + '@types/multer': 1.4.13 + express: 4.21.2 + reflect-metadata: 0.2.2 + validator: 13.15.20 + transitivePeerDependencies: + - supports-color + '@tufjs/canonical-json@2.0.0': {} '@tufjs/models@3.0.1': @@ -3868,6 +4305,10 @@ snapshots: '@tufjs/canonical-json': 2.0.0 minimatch: 9.0.5 + '@types/accepts@1.3.7': + dependencies: + '@types/node': 24.9.2 + '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 @@ -3877,6 +4318,15 @@ snapshots: dependencies: '@types/node': 24.9.2 + '@types/content-disposition@0.5.9': {} + + '@types/cookies@0.9.2': + dependencies: + '@types/connect': 3.4.38 + '@types/express': 5.0.5 + '@types/keygrip': 1.0.6 + '@types/node': 24.9.2 + '@types/cors@2.8.19': dependencies: '@types/node': 24.9.2 @@ -3896,12 +4346,35 @@ snapshots: '@types/express-serve-static-core': 5.1.0 '@types/serve-static': 1.15.10 + '@types/http-assert@1.5.6': {} + '@types/http-errors@2.0.5': {} '@types/jasmine@5.1.12': {} + '@types/keygrip@1.0.6': {} + + '@types/koa-compose@3.2.9': + dependencies: + '@types/koa': 2.15.0 + + '@types/koa@2.15.0': + dependencies: + '@types/accepts': 1.3.7 + '@types/content-disposition': 0.5.9 + '@types/cookies': 0.9.2 + '@types/http-assert': 1.5.6 + '@types/http-errors': 2.0.5 + '@types/keygrip': 1.0.6 + '@types/koa-compose': 3.2.9 + '@types/node': 24.9.2 + '@types/mime@1.3.5': {} + '@types/multer@1.4.13': + dependencies: + '@types/express': 5.0.5 + '@types/node@24.9.2': dependencies: undici-types: 7.16.0 @@ -3925,9 +4398,9 @@ snapshots: '@types/node': 24.9.2 '@types/send': 0.17.6 - '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.11(@types/node@24.9.2)(sass@1.90.0))': + '@vitejs/plugin-basic-ssl@2.1.0(vite@7.1.11(@types/node@24.9.2)(sass@1.90.0)(yaml@2.8.1))': dependencies: - vite: 7.1.11(@types/node@24.9.2)(sass@1.90.0) + vite: 7.1.11(@types/node@24.9.2)(sass@1.90.0)(yaml@2.8.1) '@yarnpkg/lockfile@1.1.0': {} @@ -3999,6 +4472,8 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.1 + array-flatten@1.1.1: {} + balanced-match@1.0.2: {} base64id@2.0.0: {} @@ -4146,6 +4621,12 @@ snapshots: strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cliui@8.0.1: + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 7.0.0 + cliui@9.0.1: dependencies: string-width: 7.2.0 @@ -4171,6 +4652,10 @@ snapshots: transitivePeerDependencies: - supports-color + content-disposition@0.5.4: + dependencies: + safe-buffer: 5.2.1 + content-disposition@1.0.0: dependencies: safe-buffer: 5.2.1 @@ -4181,8 +4666,12 @@ snapshots: convert-source-map@2.0.0: {} + cookie-signature@1.0.6: {} + cookie-signature@1.2.2: {} + cookie@0.7.1: {} + cookie@0.7.2: {} cors@2.8.5: @@ -4380,6 +4869,42 @@ snapshots: dependencies: express: 5.1.0 + express@4.21.2: + dependencies: + accepts: 1.3.8 + array-flatten: 1.1.1 + body-parser: 1.20.3 + content-disposition: 0.5.4 + content-type: 1.0.5 + 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.13.0 + 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 + transitivePeerDependencies: + - supports-color + express@5.1.0: dependencies: accepts: 2.0.0 @@ -4440,6 +4965,18 @@ snapshots: transitivePeerDependencies: - supports-color + finalhandler@1.3.1: + 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.1 + unpipe: 1.0.0 + transitivePeerDependencies: + - supports-color + finalhandler@2.1.0: dependencies: debug: 4.4.3 @@ -4462,8 +4999,16 @@ snapshots: forwarded@0.2.0: {} + fresh@0.5.2: {} + fresh@2.0.0: {} + fs-extra@11.3.2: + dependencies: + graceful-fs: 4.2.11 + jsonfile: 6.2.0 + universalify: 2.0.1 + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 @@ -4537,6 +5082,15 @@ snapshots: graceful-fs@4.2.11: {} + handlebars@4.7.8: + dependencies: + minimist: 1.2.8 + neo-async: 2.6.2 + source-map: 0.6.1 + wordwrap: 1.0.0 + optionalDependencies: + uglify-js: 3.19.3 + has-flag@4.0.0: {} has-symbols@1.1.0: {} @@ -4670,6 +5224,8 @@ snapshots: is-unicode-supported@2.1.0: {} + is-what@4.1.16: {} + isbinaryfile@4.0.10: {} isexe@2.0.0: {} @@ -4745,6 +5301,12 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonfile@6.2.0: + dependencies: + universalify: 2.0.1 + optionalDependencies: + graceful-fs: 4.2.11 + jsonparse@1.3.1: {} karma-chrome-launcher@3.2.0: @@ -4894,8 +5456,16 @@ snapshots: media-typer@1.1.0: {} + merge-anything@5.1.7: + dependencies: + is-what: 4.1.16 + + merge-descriptors@1.0.3: {} + merge-descriptors@2.0.0: {} + methods@1.1.2: {} + micromatch@4.0.8: dependencies: braces: 3.0.3 @@ -4914,6 +5484,8 @@ snapshots: dependencies: mime-db: 1.54.0 + mime@1.6.0: {} + mime@2.6.0: {} mimic-function@5.0.1: {} @@ -5010,6 +5582,8 @@ snapshots: negotiator@1.0.0: {} + neo-async@2.6.2: {} + node-addon-api@6.1.0: optional: true @@ -5185,6 +5759,8 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.2 + path-to-regexp@0.1.12: {} + path-to-regexp@8.3.0: {} picocolors@1.1.1: {} @@ -5350,6 +5926,24 @@ snapshots: semver@7.7.3: {} + send@0.19.0: + dependencies: + debug: 2.6.9 + depd: 2.0.0 + destroy: 1.2.0 + encodeurl: 1.0.2 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 0.5.2 + http-errors: 2.0.0 + mime: 1.6.0 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.1 + transitivePeerDependencies: + - supports-color + send@1.2.0: dependencies: debug: 4.4.3 @@ -5366,6 +5960,15 @@ snapshots: transitivePeerDependencies: - supports-color + serve-static@1.16.2: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.0 + transitivePeerDependencies: + - supports-color + serve-static@2.2.0: dependencies: encodeurl: 2.0.0 @@ -5591,8 +6194,17 @@ snapshots: toidentifier@1.0.1: {} + ts-deepmerge@7.0.3: {} + tslib@2.8.1: {} + tsoa@6.6.0: + dependencies: + '@tsoa/cli': 6.6.0 + '@tsoa/runtime': 6.6.0 + transitivePeerDependencies: + - supports-color + tuf-js@3.1.0: dependencies: '@tufjs/models': 3.0.1 @@ -5616,6 +6228,9 @@ snapshots: ua-parser-js@0.7.41: {} + uglify-js@3.19.3: + optional: true + undici-types@7.16.0: {} unique-filename@4.0.0: @@ -5628,6 +6243,8 @@ snapshots: universalify@0.1.2: {} + universalify@2.0.1: {} + unpipe@1.0.0: {} update-browserslist-db@1.1.4(browserslist@4.27.0): @@ -5649,9 +6266,11 @@ snapshots: validate-npm-package-name@6.0.2: {} + validator@13.15.20: {} + vary@1.1.2: {} - vite@7.1.11(@types/node@24.9.2)(sass@1.90.0): + vite@7.1.11(@types/node@24.9.2)(sass@1.90.0)(yaml@2.8.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -5663,6 +6282,7 @@ snapshots: '@types/node': 24.9.2 fsevents: 2.3.3 sass: 1.90.0 + yaml: 2.8.1 void-elements@2.0.1: {} @@ -5686,6 +6306,8 @@ snapshots: dependencies: isexe: 3.1.1 + wordwrap@1.0.0: {} + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -5722,8 +6344,12 @@ snapshots: yallist@5.0.0: {} + yaml@2.8.1: {} + yargs-parser@20.2.9: {} + yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} yargs@16.2.0: @@ -5736,6 +6362,16 @@ snapshots: y18n: 5.0.8 yargs-parser: 20.2.9 + yargs@17.7.2: + dependencies: + cliui: 8.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + string-width: 4.2.3 + y18n: 5.0.8 + yargs-parser: 21.1.1 + yargs@18.0.0: dependencies: cliui: 9.0.1 diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 58ecbba..825cf57 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -1,3 +1,9 @@ packages: - - 'packages/*' - - 'libs/*' + - packages/* + - libs/* + +onlyBuiltDependencies: + - '@parcel/watcher' + - esbuild + - lmdb + - msgpackr-extract diff --git a/routes.hbs b/routes.hbs new file mode 100644 index 0000000..868bfe7 --- /dev/null +++ b/routes.hbs @@ -0,0 +1,223 @@ +// @ts-nocheck +// This file was copied from https://github.com/lukeautry/tsoa/blob/v6.6.0/packages/cli/src/routeGeneration/templates/express.hbs to add the above line, please keep up to date +/* tslint:disable */ +/* eslint-disable */ +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa +import type { TsoaRoute } from '@tsoa/runtime'; +import { fetchMiddlewares, ExpressTemplateService } from '@tsoa/runtime'; +{{#each controllers}} +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa +import { {{name}} } from '{{modulePath}}.js'; +{{/each}} +{{#if authenticationModule}} +import { expressAuthentication } from '{{authenticationModule}}.js'; +// @ts-ignore - no great way to install types from subpackage +{{/if}} +{{#if iocModule}} +import { iocContainer } from '{{iocModule}}'; +import type { IocContainer, IocContainerFactory } from '@tsoa/runtime'; +{{/if}} +import type { Request as ExRequest, Response as ExResponse, RequestHandler, Router } from 'express'; +{{#if useFileUploads}} +{{#if esm}} +import multer from 'multer'; +{{else}} +const multer = require('multer'); +{{/if}} + +{{/if}} + +{{#if authenticationModule}} +const expressAuthenticationRecasted = expressAuthentication as (req: ExRequest, securityName: string, scopes?: string[], res?: ExResponse) => Promise; +{{/if}} + + +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + +const models: TsoaRoute.Models = { + {{#each models}} + "{{@key}}": { + {{#if enums}} + "dataType": "refEnum", + "enums": {{{json enums}}}, + {{/if}} + {{#if properties}} + "dataType": "refObject", + "properties": { + {{#each properties}} + "{{@key}}": {{{json this}}}, + {{/each}} + }, + "additionalProperties": {{{json additionalProperties}}}, + {{/if}} + {{#if type}} + "dataType": "refAlias", + "type": {{{json type}}}, + {{/if}} + }, + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + {{/each}} +}; +const templateService = new ExpressTemplateService(models, {{{ json minimalSwaggerConfig}}}); + +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + + + +{{#if useFileUploads}} +export function RegisterRoutes(app: Router,opts?:{multer?:ReturnType}) { +{{else}} +export function RegisterRoutes(app: Router) { +{{/if}} + + // ########################################################################################################### + // NOTE: If you do not see routes for all of your controllers in this file, then you might not have informed tsoa of where to look + // Please look into the "controllerPathGlobs" config option described in the readme: https://github.com/lukeautry/tsoa + // ########################################################################################################### + + {{#if useFileUploads}} + const upload = opts?.multer || multer({{{json multerOpts}}}); + {{/if}} + + + {{#each controllers}} + {{#each actions}} + const args{{../name}}_{{name}}: Record = { + {{#each parameters}} + {{@key}}: {{{json this}}}, + {{/each}} + }; + app.{{method}}('{{fullPath}}', + {{#if security.length}} + authenticateMiddleware({{json security}}), + {{/if}} + {{#if uploadFile}} + upload.fields([ + {{#each uploadFileName}} + { + name: {{json name}}, + {{#if maxCount}} + maxCount: {{maxCount}} + {{/if}} + }{{#if @last}}{{else}},{{/if}} + {{/each}} + ]), + {{/if}} + ...(fetchMiddlewares({{../name}})), + ...(fetchMiddlewares({{../name}}.prototype.{{name}})), + + async function {{../name}}_{{name}}(request: ExRequest, response: ExResponse, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + let validatedArgs: any[] = []; + try { + validatedArgs = templateService.getValidatedArgs({ args: args{{../name}}_{{name}}, request, response }); + + {{#if ../../iocModule}} + const container: IocContainer = typeof iocContainer === 'function' ? (iocContainer as IocContainerFactory)(request) : iocContainer; + + const controller: any = await container.get<{{../name}}>({{../name}}); + if (typeof controller['setStatus'] === 'function') { + controller.setStatus(undefined); + } + {{else}} + const controller = new {{../name}}(); + {{/if}} + + await templateService.apiHandler({ + methodName: '{{name}}', + controller, + response, + next, + validatedArgs, + successStatus: {{successStatus}}, + }); + } catch (err) { + return next(err); + } + }); + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + {{/each}} + {{/each}} + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + {{#if useSecurity}} + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + function authenticateMiddleware(security: TsoaRoute.Security[] = []) { + return async function runAuthenticationMiddleware(request: any, response: any, next: any) { + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + // keep track of failed auth attempts so we can hand back the most + // recent one. This behavior was previously existing so preserving it + // here + const failedAttempts: any[] = []; + const pushAndRethrow = (error: any) => { + failedAttempts.push(error); + throw error; + }; + + const secMethodOrPromises: Promise[] = []; + for (const secMethod of security) { + if (Object.keys(secMethod).length > 1) { + const secMethodAndPromises: Promise[] = []; + + for (const name in secMethod) { + secMethodAndPromises.push( + expressAuthenticationRecasted(request, name, secMethod[name], response) + .catch(pushAndRethrow) + ); + } + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + secMethodOrPromises.push(Promise.all(secMethodAndPromises) + .then(users => { return users[0]; })); + } else { + for (const name in secMethod) { + secMethodOrPromises.push( + expressAuthenticationRecasted(request, name, secMethod[name], response) + .catch(pushAndRethrow) + ); + } + } + } + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + + try { + request['user'] = await Promise.any(secMethodOrPromises); + + // Response was sent in middleware, abort + if (response.writableEnded) { + return; + } + + next(); + } + catch(err) { + // Show most recent error as response + const error = failedAttempts.pop(); + error.status = error.status || 401; + + // Response was sent in middleware, abort + if (response.writableEnded) { + return; + } + next(error); + } + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa + } + } + {{/if}} + + // WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa +} + +// WARNING: This file was auto-generated with tsoa. Please do not modify it. Re-run tsoa to re-generate this file: https://github.com/lukeautry/tsoa diff --git a/tsoa.json b/tsoa.json new file mode 100644 index 0000000..1e978cf --- /dev/null +++ b/tsoa.json @@ -0,0 +1,47 @@ +{ + "entryFile": "packages/api/src/index.ts", + "noImplicitAdditionalProperties": "throw-on-extras", + "controllerPathGlobs": [ + "packages/api/src/controllers/**/*.ts" + ], + "routes": { + "routesDir": "packages/api/src/generated", + "middleware": "express", + "authenticationModule": "packages/api/src/middleware/authentication.ts", + "middlewareTemplate": "routes.hbs" + }, + "spec": { + "outputDirectory": "packages/frontend/src/generated-api", + "specVersion": 3, + "securityDefinitions": { + "bearerAuth": { + "type": "http", + "scheme": "Bearer", + "description": "JWT token", + "bearerFormat": "JWT" + } + }, + "basePath": "/api/v1", + "servers": [ + { + "url": "https://localhost:8080/api/v1", + "description": "Development server" + }, + { + "url": "https://tcc-member-db-4bfaysdsja-ew.a.run.app/api/v1", + "description": "Production server" + } + ], + "info": { + "title": "Tcc Member API", + "description": "API for the TCC Member Database", + "version": "1.0.0", + "contact": { + "name": "TCC", + "url": "https://taekwondo-chemnitz-toni714.de/kontakt", + "email": "toniwalter.blue@gmail.com" + } + } + } +} + \ No newline at end of file