diff --git a/README.md b/README.md index e1b869151..adacee0b9 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,13 @@ contains backstage plugins written and maintained by myself This plugin provides a way to run [Renovate](https://github.com/renovatebot/renovate) against repositories to extract reports and display them in the Backstage UI on an organization scale. See [@secustor/backstage-plugin-renovate](./plugins/renovate/README.md) for more information. +**Supported features:** + +- Organization-wide Renovate report aggregation +- Integration with Backstage UI +- Automated dependency update insights +- Report extraction and visualization + ### Scaffolder Backend Module Filter Utilities This plugin provides a set of utilities to filter modules in the backend scaffolder. diff --git a/app-config.yaml b/app-config.yaml index 4227947fc..62be58e46 100644 --- a/app-config.yaml +++ b/app-config.yaml @@ -67,6 +67,11 @@ backend: connection: ':memory:' # workingDirectory: /tmp # Use this to configure a working directory for the scaffolder, defaults to the OS temp-dir + actions: + pluginSources: + - 'catalog' + - 'renovate' + integrations: github: - host: github.com diff --git a/packages/backend/package.json b/packages/backend/package.json index e1c30440c..a4a2c1c8a 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -30,6 +30,7 @@ "@backstage/plugin-catalog-backend-module-backstage-openapi": "^0.5.2", "@backstage/plugin-catalog-backend-module-github": "^0.10.0", "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "^0.2.8", + "@backstage/plugin-mcp-actions-backend": "^0.1.0", "@backstage/plugin-permission-common": "^0.9.0", "@backstage/plugin-permission-node": "^0.10.0", "@backstage/plugin-proxy-backend": "^0.6.2", diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index c5bd6b362..c8da95f29 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -25,6 +25,8 @@ backend.add(import('@backstage/plugin-search-backend-module-techdocs')); backend.add(import('@backstage/plugin-techdocs-backend')); +backend.add(import('@backstage/plugin-mcp-actions-backend')); + backend.add(import('@secustor/backstage-plugin-renovate-backend')); backend.add( import('@secustor/backstage-plugin-renovate-backend-module-runtime-direct'), diff --git a/plugins/renovate-backend-module-runtime-s3/config.d.ts b/plugins/renovate-backend-module-runtime-s3/config.d.ts index f1e79c040..9c607dbc4 100644 --- a/plugins/renovate-backend-module-runtime-s3/config.d.ts +++ b/plugins/renovate-backend-module-runtime-s3/config.d.ts @@ -27,4 +27,4 @@ export interface Config { }; }; }; -} \ No newline at end of file +} diff --git a/plugins/renovate-backend-module-runtime-s3/src/config.ts b/plugins/renovate-backend-module-runtime-s3/src/config.ts index 2dc056e72..1bdf32bd7 100644 --- a/plugins/renovate-backend-module-runtime-s3/src/config.ts +++ b/plugins/renovate-backend-module-runtime-s3/src/config.ts @@ -16,7 +16,7 @@ export function getS3Config(config: Config, logger: LoggerService): S3Config { key: config.getString('key'), endpoint: config.getOptionalString('endpoint'), }; - + logger.debug('S3 configuration loaded successfully', { bucket: settings.bucket, region: settings.region, @@ -30,4 +30,4 @@ export function getS3Config(config: Config, logger: LoggerService): S3Config { logger.error(message); throw new Error(message); } -} \ No newline at end of file +} diff --git a/plugins/renovate-backend-module-runtime-s3/src/runtime.ts b/plugins/renovate-backend-module-runtime-s3/src/runtime.ts index 3f5be6f6b..a9e4a9ef9 100644 --- a/plugins/renovate-backend-module-runtime-s3/src/runtime.ts +++ b/plugins/renovate-backend-module-runtime-s3/src/runtime.ts @@ -22,8 +22,8 @@ class ReportReader { }; this.s3Client = new S3Client(clientConfig); - this.logger.debug('Initialized S3 client', { - bucket: config.bucket, + this.logger.debug('Initialized S3 client', { + bucket: config.bucket, region: config.region, usingEndpoint: !!config.endpoint, }); @@ -34,7 +34,9 @@ class ReportReader { if (!objectKey) { throw new Error('S3 key is required'); } - this.logger.debug(`Reading report from S3: ${this.config.bucket}/${objectKey}`); + this.logger.debug( + `Reading report from S3: ${this.config.bucket}/${objectKey}`, + ); try { const response = await this.s3Client.send( @@ -51,7 +53,8 @@ class ReportReader { const fileContent = await response.Body.transformToString(); return this.parseReport(fileContent, objectKey); } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error); + const errorMessage = + error instanceof Error ? error.message : String(error); this.logger.warn(`Error reading report from S3: ${errorMessage}`); throw error; } @@ -63,19 +66,22 @@ class ReportReader { return { problems: report.problems || [], repositories: Object.fromEntries( - Object.entries(report.repositories || {}).map(([repoKey, value]: [string, any]) => [ - repoKey, - { - problems: value?.problems || [], - branches: value?.branches || [], - packageFiles: value?.packageFiles || {}, - libYears: value?.libYears, - } - ]) - ) + Object.entries(report.repositories || {}).map( + ([repoKey, value]: [string, any]) => [ + repoKey, + { + problems: value?.problems || [], + branches: value?.branches || [], + packageFiles: value?.packageFiles || {}, + libYears: value?.libYears, + }, + ], + ), + ), }; } catch (error) { - const errorMessage = error instanceof Error ? error.message : String(error); + const errorMessage = + error instanceof Error ? error.message : String(error); this.logger.error(`Invalid JSON in ${key}: ${errorMessage}`); throw new Error(`Invalid JSON in renovate report: ${errorMessage}`); } @@ -83,21 +89,29 @@ class ReportReader { } class ReportFormatter { - static formatResponse(targetRepo: string, data?: unknown, error?: string): RenovateRunResult { + static formatResponse( + targetRepo: string, + data?: unknown, + error?: string, + ): RenovateRunResult { const response = { - msg: error ? `Error reading report: ${error}` : 'Renovate report extracted from file', + msg: error + ? `Error reading report: ${error}` + : 'Renovate report extracted from file', logContext: targetRepo || 'unknown', report: { problems: [], - repositories: data ? { - [targetRepo]: { - problems: (data as any)?.problems || [], - branches: (data as any)?.branches || [], - packageFiles: (data as any)?.packageFiles || {}, - libYears: (data as any)?.libYears, - } - } : {} - } + repositories: data + ? { + [targetRepo]: { + problems: (data as any)?.problems || [], + branches: (data as any)?.branches || [], + packageFiles: (data as any)?.packageFiles || {}, + libYears: (data as any)?.libYears, + }, + } + : {}, + }, }; return { stdout: Readable.from(`${JSON.stringify(response)}\n`), @@ -126,13 +140,21 @@ export class S3 implements RenovateWrapper { if (!repositoryData) { logger.warn(`No data found for repository: ${targetRepo}`); - return ReportFormatter.formatResponse(targetRepo, undefined, "no report found for this repository"); + return ReportFormatter.formatResponse( + targetRepo, + undefined, + 'no report found for this repository', + ); } logger.debug(`Found data for repository: ${targetRepo}`); return ReportFormatter.formatResponse(targetRepo, repositoryData); } catch (error) { - return ReportFormatter.formatResponse(targetRepo, undefined, String(error)); + return ReportFormatter.formatResponse( + targetRepo, + undefined, + String(error), + ); } } } diff --git a/plugins/renovate-backend/src/plugin.ts b/plugins/renovate-backend/src/plugin.ts index 95a09c7db..bca246004 100644 --- a/plugins/renovate-backend/src/plugin.ts +++ b/plugins/renovate-backend/src/plugin.ts @@ -2,8 +2,13 @@ import { coreServices, createBackendPlugin, } from '@backstage/backend-plugin-api'; +import { actionsRegistryServiceRef } from '@backstage/backend-plugin-api/alpha'; import { createRouter } from './service/router'; -import { RenovateWrapper } from '@secustor/backstage-plugin-renovate-common'; +import { + renovateReport, + RenovateWrapper, + targetRepo, +} from '@secustor/backstage-plugin-renovate-common'; import { RenovateRunner } from './wrapper'; import { RouterOptions } from './service/types'; import { DatabaseHandler } from './service/databaseHandler'; @@ -51,6 +56,7 @@ export const renovatePlugin = createBackendPlugin({ env.registerInit({ deps: { + actionsRegistry: actionsRegistryServiceRef, rootConfig: coreServices.rootConfig, logger: coreServices.logger, httpRouter: coreServices.httpRouter, @@ -60,11 +66,16 @@ export const renovatePlugin = createBackendPlugin({ auth: coreServices.auth, }, async init(options) { - const { database, httpRouter, logger } = options; + const { actionsRegistry, database, httpRouter, logger } = options; + + const databaseHandler = await DatabaseHandler.create({ + database, + logger, + }); const routerOptions: RouterOptions = { ...options, - databaseHandler: await DatabaseHandler.create({ database, logger }), + databaseHandler, runtimes, queueFactories, }; @@ -73,6 +84,35 @@ export const renovatePlugin = createBackendPlugin({ await scheduleJobSync(renovateRunner, routerOptions); await scheduleCleanupTask(routerOptions); + actionsRegistry.register({ + name: 'run-renovate', + title: 'Run Renovate', + description: `Run Renovate against a target repository to extract dependencies and generates a new report. + The report consists of: + - a list of dependencies grouped by under 'packageFile' by manager (e.g. npm, pip, etc.) and their updates if available + - a list of branches Renovate has created or would create and the updates the branch contain + - a list of problems Renovate has detected while processing the repository + - a record of libYearsWithStatus which contains the summarized age of dependencies grouped by their manager / ecosystem + - a summary dependencyStatus which contains the number of dependencies and the number of outdated dependencies`, + attributes: {}, + schema: { + input: () => targetRepo, + output: () => renovateReport, + }, + action: async ({ input, logger: localLogger }) => { + const report = await renovateRunner.renovate( + { + id: 'run-renovate', + target: input, + }, + localLogger, + ); + return { + output: report, + }; + }, + }); + httpRouter.use(await createRouter(renovateRunner, routerOptions)); httpRouter.addAuthPolicy({ path: '/health', diff --git a/yarn.lock b/yarn.lock index 3bc3928fe..7e8866b80 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4965,6 +4965,24 @@ __metadata: languageName: node linkType: hard +"@backstage/plugin-mcp-actions-backend@npm:^0.1.0": + version: 0.1.0 + resolution: "@backstage/plugin-mcp-actions-backend@npm:0.1.0" + dependencies: + "@backstage/backend-defaults": "npm:^0.11.0" + "@backstage/backend-plugin-api": "npm:^1.4.0" + "@backstage/catalog-client": "npm:^1.10.1" + "@backstage/errors": "npm:^1.2.7" + "@backstage/plugin-catalog-node": "npm:^1.17.1" + "@backstage/types": "npm:^1.2.1" + "@modelcontextprotocol/sdk": "npm:^1.12.3" + express: "npm:^4.17.1" + express-promise-router: "npm:^4.1.0" + zod: "npm:^3.22.4" + checksum: 10c0/6138ae858c95ad36c0cd4588360947264fc11d70ef069906a54affe5f401ee3eeec24e83efde79e87755ec2106b9821db3e9e5cd9ee8047fc3ac41dbbbf0ceb2 + languageName: node + linkType: hard + "@backstage/plugin-org@npm:^0.6.39": version: 0.6.40 resolution: "@backstage/plugin-org@npm:0.6.40" @@ -8721,6 +8739,25 @@ __metadata: languageName: node linkType: hard +"@modelcontextprotocol/sdk@npm:^1.12.3": + version: 1.13.0 + resolution: "@modelcontextprotocol/sdk@npm:1.13.0" + dependencies: + ajv: "npm:^6.12.6" + content-type: "npm:^1.0.5" + cors: "npm:^2.8.5" + cross-spawn: "npm:^7.0.5" + eventsource: "npm:^3.0.2" + express: "npm:^5.0.1" + express-rate-limit: "npm:^7.5.0" + pkce-challenge: "npm:^5.0.0" + raw-body: "npm:^3.0.0" + zod: "npm:^3.23.8" + zod-to-json-schema: "npm:^3.24.1" + checksum: 10c0/bbc07460659b5b4b4ecf19befd8bb8dde2aeee20123f388a0d58142da9a7a22e292fbb11b1d99ea54ae514652db129c3ec3b35fc5e9e61bf49d3bb9b221657cc + languageName: node + linkType: hard + "@module-federation/bridge-react-webpack-plugin@npm:0.9.1": version: 0.9.1 resolution: "@module-federation/bridge-react-webpack-plugin@npm:0.9.1" @@ -16658,6 +16695,16 @@ __metadata: languageName: node linkType: hard +"accepts@npm:^2.0.0": + version: 2.0.0 + resolution: "accepts@npm:2.0.0" + dependencies: + mime-types: "npm:^3.0.0" + negotiator: "npm:^1.0.0" + checksum: 10c0/98374742097e140891546076215f90c32644feacf652db48412329de4c2a529178a81aa500fbb13dd3e6cbf6e68d829037b123ac037fc9a08bcec4b87b358eef + languageName: node + linkType: hard + "acorn-globals@npm:^7.0.0": version: 7.0.1 resolution: "acorn-globals@npm:7.0.1" @@ -16829,7 +16876,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.12.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.12.2, ajv@npm:^6.12.3, ajv@npm:^6.12.4, ajv@npm:^6.12.5, ajv@npm:^6.12.6": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -17771,6 +17818,7 @@ __metadata: "@backstage/plugin-catalog-backend-module-backstage-openapi": "npm:^0.5.2" "@backstage/plugin-catalog-backend-module-github": "npm:^0.10.0" "@backstage/plugin-catalog-backend-module-scaffolder-entity-model": "npm:^0.2.8" + "@backstage/plugin-mcp-actions-backend": "npm:^0.1.0" "@backstage/plugin-permission-common": "npm:^0.9.0" "@backstage/plugin-permission-node": "npm:^0.10.0" "@backstage/plugin-proxy-backend": "npm:^0.6.2" @@ -18117,6 +18165,23 @@ __metadata: languageName: node linkType: hard +"body-parser@npm:^2.2.0": + version: 2.2.0 + resolution: "body-parser@npm:2.2.0" + dependencies: + bytes: "npm:^3.1.2" + content-type: "npm:^1.0.5" + debug: "npm:^4.4.0" + http-errors: "npm:^2.0.0" + iconv-lite: "npm:^0.6.3" + on-finished: "npm:^2.4.1" + qs: "npm:^6.14.0" + raw-body: "npm:^3.0.0" + type-is: "npm:^2.0.0" + checksum: 10c0/a9ded39e71ac9668e2211afa72e82ff86cc5ef94de1250b7d1ba9cc299e4150408aaa5f1e8b03dd4578472a3ce6d1caa2a23b27a6c18e526e48b4595174c116c + languageName: node + linkType: hard + "bonjour-service@npm:^1.2.1": version: 1.3.0 resolution: "bonjour-service@npm:1.3.0" @@ -18487,7 +18552,7 @@ __metadata: languageName: node linkType: hard -"bytes@npm:3.1.2": +"bytes@npm:3.1.2, bytes@npm:^3.1.2": version: 3.1.2 resolution: "bytes@npm:3.1.2" checksum: 10c0/76d1c43cbd602794ad8ad2ae94095cddeb1de78c5dddaa7005c51af10b0176c69971a6d88e805a90c2b6550d76636e43c40d8427a808b8645ede885de4a0358e @@ -19624,6 +19689,15 @@ __metadata: languageName: node linkType: hard +"content-disposition@npm:^1.0.0": + version: 1.0.0 + resolution: "content-disposition@npm:1.0.0" + dependencies: + safe-buffer: "npm:5.2.1" + checksum: 10c0/c7b1ba0cea2829da0352ebc1b7f14787c73884bc707c8bc2271d9e3bf447b372270d09f5d3980dc5037c749ceef56b9a13fccd0b0001c87c3f12579967e4dd27 + languageName: node + linkType: hard + "content-type@npm:^1.0.4, content-type@npm:^1.0.5, content-type@npm:~1.0.4, content-type@npm:~1.0.5": version: 1.0.5 resolution: "content-type@npm:1.0.5" @@ -19776,6 +19850,13 @@ __metadata: languageName: node linkType: hard +"cookie-signature@npm:^1.2.1": + version: 1.2.2 + resolution: "cookie-signature@npm:1.2.2" + checksum: 10c0/54e05df1a293b3ce81589b27dddc445f462f6fa6812147c033350cd3561a42bc14481674e05ed14c7bd0ce1e8bb3dc0e40851bad75415733711294ddce0b7bc6 + languageName: node + linkType: hard + "cookie@npm:0.7.1": version: 0.7.1 resolution: "cookie@npm:0.7.1" @@ -19783,7 +19864,7 @@ __metadata: languageName: node linkType: hard -"cookie@npm:0.7.2, cookie@npm:^0.7.0, cookie@npm:^0.7.2": +"cookie@npm:0.7.2, cookie@npm:^0.7.0, cookie@npm:^0.7.1, cookie@npm:^0.7.2": version: 0.7.2 resolution: "cookie@npm:0.7.2" checksum: 10c0/9596e8ccdbf1a3a88ae02cf5ee80c1c50959423e1022e4e60b91dd87c622af1da309253d8abdb258fb5e3eacb4f08e579dc58b4897b8087574eee0fd35dfa5d2 @@ -21584,7 +21665,7 @@ __metadata: languageName: node linkType: hard -"encodeurl@npm:~2.0.0": +"encodeurl@npm:^2.0.0, encodeurl@npm:~2.0.0": version: 2.0.0 resolution: "encodeurl@npm:2.0.0" checksum: 10c0/5d317306acb13e6590e28e27924c754163946a2480de11865c991a3a7eed4315cd3fba378b543ca145829569eefe9b899f3d84bb09870f675ae60bc924b01ceb @@ -22436,7 +22517,7 @@ __metadata: languageName: node linkType: hard -"etag@npm:~1.8.1": +"etag@npm:^1.8.1, etag@npm:~1.8.1": version: 1.8.1 resolution: "etag@npm:1.8.1" checksum: 10c0/12be11ef62fb9817314d790089a0a49fae4e1b50594135dcb8076312b7d7e470884b5100d249b28c18581b7fd52f8b485689ffae22a11ed9ec17377a33a08f84 @@ -22478,6 +22559,22 @@ __metadata: languageName: node linkType: hard +"eventsource-parser@npm:^3.0.1": + version: 3.0.2 + resolution: "eventsource-parser@npm:3.0.2" + checksum: 10c0/067c6e60b7c68a4577630cc7e11d2aaeef52005e377a213308c7c2350596a175d5a179671d85f570726dce3f451c15d174ece4479ce68a1805686c88950d08dd + languageName: node + linkType: hard + +"eventsource@npm:^3.0.2": + version: 3.0.7 + resolution: "eventsource@npm:3.0.7" + dependencies: + eventsource-parser: "npm:^3.0.1" + checksum: 10c0/c48a73c38f300e33e9f11375d4ee969f25cbb0519608a12378a38068055ae8b55b6e0e8a49c3f91c784068434efe1d9f01eb49b6315b04b0da9157879ce2f67d + languageName: node + linkType: hard + "evp_bytestokey@npm:^1.0.0, evp_bytestokey@npm:^1.0.3": version: 1.0.3 resolution: "evp_bytestokey@npm:1.0.3" @@ -22671,6 +22768,41 @@ __metadata: languageName: node linkType: hard +"express@npm:^5.0.1": + version: 5.1.0 + resolution: "express@npm:5.1.0" + dependencies: + accepts: "npm:^2.0.0" + body-parser: "npm:^2.2.0" + content-disposition: "npm:^1.0.0" + content-type: "npm:^1.0.5" + cookie: "npm:^0.7.1" + cookie-signature: "npm:^1.2.1" + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + finalhandler: "npm:^2.1.0" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + merge-descriptors: "npm:^2.0.0" + mime-types: "npm:^3.0.0" + on-finished: "npm:^2.4.1" + once: "npm:^1.4.0" + parseurl: "npm:^1.3.3" + proxy-addr: "npm:^2.0.7" + qs: "npm:^6.14.0" + range-parser: "npm:^1.2.1" + router: "npm:^2.2.0" + send: "npm:^1.1.0" + serve-static: "npm:^2.2.0" + statuses: "npm:^2.0.1" + type-is: "npm:^2.0.1" + vary: "npm:^1.1.2" + checksum: 10c0/80ce7c53c5f56887d759b94c3f2283e2e51066c98d4b72a4cc1338e832b77f1e54f30d0239cc10815a0f849bdb753e6a284d2fa48d4ab56faf9c501f55d751d6 + languageName: node + linkType: hard + "extend@npm:3.0.2, extend@npm:^3.0.0, extend@npm:^3.0.2, extend@npm:~3.0.2": version: 3.0.2 resolution: "extend@npm:3.0.2" @@ -23064,6 +23196,20 @@ __metadata: languageName: node linkType: hard +"finalhandler@npm:^2.1.0": + version: 2.1.0 + resolution: "finalhandler@npm:2.1.0" + dependencies: + debug: "npm:^4.4.0" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + on-finished: "npm:^2.4.1" + parseurl: "npm:^1.3.3" + statuses: "npm:^2.0.1" + checksum: 10c0/da0bbca6d03873472ee890564eb2183f4ed377f25f3628a0fc9d16dac40bed7b150a0d82ebb77356e4c6d97d2796ad2dba22948b951dddee2c8768b0d1b9fb1f + languageName: node + linkType: hard + "find-file-up@npm:^2.0.1": version: 2.0.1 resolution: "find-file-up@npm:2.0.1" @@ -23415,6 +23561,13 @@ __metadata: languageName: node linkType: hard +"fresh@npm:^2.0.0": + version: 2.0.0 + resolution: "fresh@npm:2.0.0" + checksum: 10c0/0557548194cb9a809a435bf92bcfbc20c89e8b5eb38861b73ced36750437251e39a111fc3a18b98531be9dd91fe1411e4969f229dc579ec0251ce6c5d4900bbc + languageName: node + linkType: hard + "fromentries@npm:^1.3.1": version: 1.3.2 resolution: "fromentries@npm:1.3.2" @@ -24838,7 +24991,7 @@ __metadata: languageName: node linkType: hard -"http-errors@npm:2.0.0": +"http-errors@npm:2.0.0, http-errors@npm:^2.0.0": version: 2.0.0 resolution: "http-errors@npm:2.0.0" dependencies: @@ -29136,6 +29289,13 @@ __metadata: languageName: node linkType: hard +"merge-descriptors@npm:^2.0.0": + version: 2.0.0 + resolution: "merge-descriptors@npm:2.0.0" + checksum: 10c0/95389b7ced3f9b36fbdcf32eb946dc3dd1774c2fdf164609e55b18d03aa499b12bd3aae3a76c1c7185b96279e9803525550d3eb292b5224866060a288f335cb3 + languageName: node + linkType: hard + "merge-stream@npm:^2.0.0": version: 2.0.0 resolution: "merge-stream@npm:2.0.0" @@ -29537,7 +29697,7 @@ __metadata: languageName: node linkType: hard -"mime-db@npm:>= 1.43.0 < 2": +"mime-db@npm:>= 1.43.0 < 2, mime-db@npm:^1.54.0": version: 1.54.0 resolution: "mime-db@npm:1.54.0" checksum: 10c0/8d907917bc2a90fa2df842cdf5dfeaf509adc15fe0531e07bb2f6ab15992416479015828d6a74200041c492e42cce3ebf78e5ce714388a0a538ea9c53eece284 @@ -29553,6 +29713,15 @@ __metadata: languageName: node linkType: hard +"mime-types@npm:^3.0.0, mime-types@npm:^3.0.1": + version: 3.0.1 + resolution: "mime-types@npm:3.0.1" + dependencies: + mime-db: "npm:^1.54.0" + checksum: 10c0/bd8c20d3694548089cf229016124f8f40e6a60bbb600161ae13e45f793a2d5bb40f96bbc61f275836696179c77c1d6bf4967b2a75e0a8ad40fe31f4ed5be4da5 + languageName: node + linkType: hard + "mime@npm:1.6.0": version: 1.6.0 resolution: "mime@npm:1.6.0" @@ -31953,7 +32122,7 @@ __metadata: languageName: node linkType: hard -"parseurl@npm:^1.3.2, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": +"parseurl@npm:^1.3.2, parseurl@npm:^1.3.3, parseurl@npm:~1.3.2, parseurl@npm:~1.3.3": version: 1.3.3 resolution: "parseurl@npm:1.3.3" checksum: 10c0/90dd4760d6f6174adb9f20cf0965ae12e23879b5f5464f38e92fce8073354341e4b3b76fa3d878351efe7d01e617121955284cfd002ab087fba1a0726ec0b4f5 @@ -32404,6 +32573,13 @@ __metadata: languageName: node linkType: hard +"pkce-challenge@npm:^5.0.0": + version: 5.0.0 + resolution: "pkce-challenge@npm:5.0.0" + checksum: 10c0/c6706d627fdbb6f22bf8cc5d60d96d6b6a7bb481399b336a3d3f4e9bfba3e167a2c32f8ec0b5e74be686a0ba3bcc9894865d4c2dd1b91cea4c05dba1f28602c3 + languageName: node + linkType: hard + "pkg-dir@npm:^4.2.0": version: 4.2.0 resolution: "pkg-dir@npm:4.2.0" @@ -33250,7 +33426,7 @@ __metadata: languageName: node linkType: hard -"proxy-addr@npm:~2.0.7": +"proxy-addr@npm:^2.0.7, proxy-addr@npm:~2.0.7": version: 2.0.7 resolution: "proxy-addr@npm:2.0.7" dependencies: @@ -33543,6 +33719,18 @@ __metadata: languageName: node linkType: hard +"raw-body@npm:^3.0.0": + version: 3.0.0 + resolution: "raw-body@npm:3.0.0" + dependencies: + bytes: "npm:3.1.2" + http-errors: "npm:2.0.0" + iconv-lite: "npm:0.6.3" + unpipe: "npm:1.0.0" + checksum: 10c0/f8daf4b724064a4811d118745a781ca0fb4676298b8adadfd6591155549cfea0a067523cf7dd3baeb1265fecc9ce5dfb2fc788c12c66b85202a336593ece0f87 + languageName: node + linkType: hard + "raw-loader@npm:^4.0.2": version: 4.0.2 resolution: "raw-loader@npm:4.0.2" @@ -35281,6 +35469,19 @@ __metadata: languageName: unknown linkType: soft +"router@npm:^2.2.0": + version: 2.2.0 + resolution: "router@npm:2.2.0" + dependencies: + debug: "npm:^4.4.0" + depd: "npm:^2.0.0" + is-promise: "npm:^4.0.0" + parseurl: "npm:^1.3.3" + path-to-regexp: "npm:^8.0.0" + checksum: 10c0/3279de7450c8eae2f6e095e9edacbdeec0abb5cb7249c6e719faa0db2dba43574b4fff5892d9220631c9abaff52dd3cad648cfea2aaace845e1a071915ac8867 + languageName: node + linkType: hard + "rrweb-cssom@npm:^0.8.0": version: 0.8.0 resolution: "rrweb-cssom@npm:0.8.0" @@ -35636,6 +35837,25 @@ __metadata: languageName: node linkType: hard +"send@npm:^1.1.0, send@npm:^1.2.0": + version: 1.2.0 + resolution: "send@npm:1.2.0" + dependencies: + debug: "npm:^4.3.5" + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + etag: "npm:^1.8.1" + fresh: "npm:^2.0.0" + http-errors: "npm:^2.0.0" + mime-types: "npm:^3.0.1" + ms: "npm:^2.1.3" + on-finished: "npm:^2.4.1" + range-parser: "npm:^1.2.1" + statuses: "npm:^2.0.1" + checksum: 10c0/531bcfb5616948d3468d95a1fd0adaeb0c20818ba4a500f439b800ca2117971489e02074ce32796fd64a6772ea3e7235fe0583d8241dbd37a053dc3378eff9a5 + languageName: node + linkType: hard + "seq-queue@npm:^0.0.5": version: 0.0.5 resolution: "seq-queue@npm:0.0.5" @@ -35697,6 +35917,18 @@ __metadata: languageName: node linkType: hard +"serve-static@npm:^2.2.0": + version: 2.2.0 + resolution: "serve-static@npm:2.2.0" + dependencies: + encodeurl: "npm:^2.0.0" + escape-html: "npm:^1.0.3" + parseurl: "npm:^1.3.3" + send: "npm:^1.2.0" + checksum: 10c0/30e2ed1dbff1984836cfd0c65abf5d3f3f83bcd696c99d2d3c97edbd4e2a3ff4d3f87108a7d713640d290a7b6fe6c15ddcbc61165ab2eaad48ea8d3b52c7f913 + languageName: node + linkType: hard + "set-blocking@npm:^2.0.0": version: 2.0.0 resolution: "set-blocking@npm:2.0.0" @@ -38189,6 +38421,17 @@ __metadata: languageName: node linkType: hard +"type-is@npm:^2.0.0, type-is@npm:^2.0.1": + version: 2.0.1 + resolution: "type-is@npm:2.0.1" + dependencies: + content-type: "npm:^1.0.5" + media-typer: "npm:^1.1.0" + mime-types: "npm:^3.0.0" + checksum: 10c0/7f7ec0a060b16880bdad36824ab37c26019454b67d73e8a465ed5a3587440fbe158bc765f0da68344498235c877e7dbbb1600beccc94628ed05599d667951b99 + languageName: node + linkType: hard + "typed-array-buffer@npm:^1.0.3": version: 1.0.3 resolution: "typed-array-buffer@npm:1.0.3" @@ -40123,7 +40366,7 @@ __metadata: languageName: node linkType: hard -"zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.21.4": +"zod-to-json-schema@npm:^3.20.4, zod-to-json-schema@npm:^3.21.4, zod-to-json-schema@npm:^3.24.1": version: 3.24.5 resolution: "zod-to-json-schema@npm:3.24.5" peerDependencies: @@ -40148,10 +40391,10 @@ __metadata: languageName: node linkType: hard -"zod@npm:^3.20.0, zod@npm:^3.22.4, zod@npm:^3.23.0, zod@npm:^3.24.2": - version: 3.25.63 - resolution: "zod@npm:3.25.63" - checksum: 10c0/ce09c6ae327a66629e67340856ec19b6b4ba2c28691a2de1e618a5cc717685c2b4e9baa370cf81c34f453fc652733ecfc9a7d5d966570a22472999931abd5ada +"zod@npm:^3.20.0, zod@npm:^3.22.4, zod@npm:^3.23.0, zod@npm:^3.23.8, zod@npm:^3.24.2": + version: 3.25.67 + resolution: "zod@npm:3.25.67" + checksum: 10c0/80a0cab3033272c4ab9312198081f0c4ea88e9673c059aa36dc32024906363729db54bdb78f3dc9d5529bd1601f74974d5a56c0a23e40c6f04a9270c9ff22336 languageName: node linkType: hard