diff --git a/config/moda/configuration/default/env.yaml b/config/moda/configuration/default/env.yaml index fb0e6d7f06f4..03135c30f86e 100644 --- a/config/moda/configuration/default/env.yaml +++ b/config/moda/configuration/default/env.yaml @@ -9,3 +9,7 @@ data: RATE_LIMIT_MAX: '21' # Moda uses a non-default port for sending datadog metrics DD_DOGSTATSD_PORT: '28125' + # OTel distributed tracing — sends spans to OTel Collector via OTLP/HTTP (proto). + # Uses stamp address (not mesh) since docs-internal is not on the service mesh. + # See https://thehub.github.com/epd/engineering/dev-practicals/observability/distributed-tracing/instrumentation/ + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'https://otelcol.service.%stamp%.github.net/v1/traces' diff --git a/config/moda/configuration/production/env.yaml b/config/moda/configuration/production/env.yaml index 3ec81a4433f8..706f1c44df0d 100644 --- a/config/moda/configuration/production/env.yaml +++ b/config/moda/configuration/production/env.yaml @@ -12,3 +12,7 @@ data: # Identifies the service deployment environment as production # Equivalent to HEAVEN_DEPLOYED_ENV === 'production' MODA_PROD_SERVICE_ENV: 'true' + # OTel distributed tracing — sends spans to OTel Collector via OTLP/HTTP (proto). + # Uses stamp address (not mesh) since docs-internal is not on the service mesh. + # See https://thehub.github.com/epd/engineering/dev-practicals/observability/distributed-tracing/instrumentation/ + OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: 'https://otelcol.service.%stamp%.github.net/v1/traces' diff --git a/config/moda/secrets/production/secrets.yml b/config/moda/secrets/production/secrets.yml index 20b7ce0d3c0a..cd04b7832306 100644 --- a/config/moda/secrets/production/secrets.yml +++ b/config/moda/secrets/production/secrets.yml @@ -64,3 +64,8 @@ secrets: type: hydro_api_key owner: '@github/docs-engineering' externally_usable: true + OTEL_EXPORTER_OTLP_TRACES_HEADERS: + kind: latest_at_deployment_start + type: salt + owner: '@github/docs-engineering' + externally_usable: true diff --git a/content/billing/reference/billing-roles.md b/content/billing/reference/billing-roles.md index 6b0398868c7c..0c5d4b2ebda1 100644 --- a/content/billing/reference/billing-roles.md +++ b/content/billing/reference/billing-roles.md @@ -17,6 +17,10 @@ The following roles have access to the billing platform: * **Enterprise owners and enterprise billing managers**: Can manage billing for an enterprise account. * **Organization owners and organization billing managers**: Can manage billing for an organization on {% data variables.product.prodname_free_team %} or {% data variables.product.prodname_team %}. + + > [!NOTE] + > If your organization is owned by an enterprise account, you cannot add billing managers at the organization level. Billing for enterprise-owned organizations is managed at the enterprise level. + * **Personal accounts (non-managed)**: Can access the billing platform for their personal usage. To add a billing manager, see: @@ -38,9 +42,7 @@ You have full administrative access to your organization. You can: You can: -* View all metered usage for your organization its repositories. -* View organization-level budgets. -* Download CSV usage reports. +{% data reusables.billing.org-billing-manager-permissions %} ## Enterprise owners and enterprise billing managers @@ -51,6 +53,8 @@ You can: * Download CSV usage reports for products your enterprise is using. * Set budgets for your enterprise. * Create cost centers for all organizations within your enterprise. +* View and manage user licenses. +* Manage other billing settings, such as payment methods and billing contacts. ## Further reading diff --git a/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/enabling-extended-metadata-checks-for-your-repository.md b/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/enabling-extended-metadata-checks-for-your-repository.md index bca36230bffb..10a8f8a72579 100644 --- a/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/enabling-extended-metadata-checks-for-your-repository.md +++ b/content/code-security/how-tos/secure-your-secrets/customize-leak-detection/enabling-extended-metadata-checks-for-your-repository.md @@ -17,10 +17,14 @@ redirect_from: This article shows how you can enable extended metadata checks for individual repositories through repository settings. Alternatively, you can enable them at scale using **security configurations** at the organization or enterprise level. See [AUTOTITLE](/code-security/how-tos/secure-at-scale/configure-organization-security/establish-complete-coverage/creating-a-custom-security-configuration) or [AUTOTITLE](/code-security/how-tos/secure-at-scale/configure-enterprise-security/establish-complete-coverage/creating-a-custom-security-configuration-for-your-enterprise). +{% ifversion secret-scanning-validity-check-partner-patterns %} + ## Prerequisites Before enabling metadata checks, you need to ensure that validity checks are enabled for the repository. See [AUTOTITLE](/code-security/secret-scanning/enabling-secret-scanning-features/enabling-validity-checks-for-your-repository#enabling-validity-checks). +{% endif %} + ## Enabling extended metadata checks {% ifversion fpt or ghec %} diff --git a/content/copilot/concepts/agents/code-review.md b/content/copilot/concepts/agents/code-review.md index 8568178b8209..2f5331e07dd6 100644 --- a/content/copilot/concepts/agents/code-review.md +++ b/content/copilot/concepts/agents/code-review.md @@ -109,7 +109,7 @@ Organizations in this situation can use self-hosted runners. For more informatio Each time {% data variables.product.prodname_copilot_short %} reviews a pull request or reviews code in your IDE, your monthly quota of {% data variables.product.prodname_copilot_short %} premium requests is reduced by one. -If a repository is configured to automatically request a code review from {% data variables.product.prodname_copilot_short %} for all new pull requests, the premium request usage is applied to the pull request author's quota. +If a repository is configured to automatically request a code review from {% data variables.product.prodname_copilot_short %} for all new pull requests, the premium request usage is applied to the pull request author's quota. If a review is manually requested by another user, the usage is applied to that user's quota instead. If a pull request is created by {% data variables.product.prodname_actions %} or by a bot, the usage will apply to: @@ -120,11 +120,13 @@ If a pull request is created by {% data variables.product.prodname_actions %} or When you reach your monthly quota, you will not be able to get a code review from {% data variables.product.prodname_copilot_short %} until your quota resets. To continue to use code reviews before your quota resets, you will need to upgrade your {% data variables.product.prodname_copilot_short %} plan or enable additional premium requests. -### Quota for users without a {% data variables.product.prodname_copilot_short %} license +### Users without a {% data variables.product.prodname_copilot_short %} license or plan that includes {% data variables.copilot.copilot_code-review_short %} -Users without a {% data variables.product.prodname_copilot_short %} license do not have a monthly premium request quota. When {% data variables.copilot.copilot_code-review_short %} is enabled for these users, any premium requests they generate are billed directly to the organization or enterprise as paid overage usage. This applies to both manually requested reviews and automatic code reviews. +Users without access to {% data variables.copilot.copilot_code-review_short %} do not have a monthly premium request quota. This includes users who have no {% data variables.product.prodname_copilot_short %} license and users on the {% data variables.copilot.copilot_free_short %} plan, which does not include {% data variables.copilot.copilot_code-review_short %}. -Premium requests generated by users without a license are not attributed to any {% data variables.product.prodname_copilot_short %} plan quota. They appear as overage usage in billing reports and premium request analytics. Users with a {% data variables.product.prodname_copilot_short %} license continue to consume premium requests from their assigned plan quota. +When {% data variables.copilot.copilot_code-review_short %} is enabled for these users, any premium requests they generate are billed directly to the organization or enterprise as paid overage usage. This applies to both manually requested reviews and automatic code reviews. + +Premium requests generated by these users are not attributed to any {% data variables.product.prodname_copilot_short %} plan quota. They appear as overage usage in billing reports and premium request analytics. Users with a {% data variables.product.prodname_copilot_short %} license that includes code review continue to consume premium requests from their assigned plan quota. ## Model usage diff --git a/content/copilot/concepts/billing/copilot-requests.md b/content/copilot/concepts/billing/copilot-requests.md index 938c149c7011..3f351eeffefb 100644 --- a/content/copilot/concepts/billing/copilot-requests.md +++ b/content/copilot/concepts/billing/copilot-requests.md @@ -25,7 +25,7 @@ category: ## What is a request? -A request is any interaction where you ask {% data variables.product.prodname_copilot_short %} to do something for you—whether it’s generating code, answering a question, or helping you through an extension. Each time you send a prompt in a chat window or trigger a response from {% data variables.product.prodname_copilot_short %}, you’re making a request. +A request is any interaction where you ask {% data variables.product.prodname_copilot_short %} to do something for you—whether it's generating code, answering a question, or helping you through an extension. Each time you send a prompt in a chat window or trigger a response from {% data variables.product.prodname_copilot_short %}, you're making a request. For agentic features, only the prompts you send count as premium requests; actions {% data variables.product.prodname_copilot_short %} takes autonomously to complete your task, such as tool calls, do not. For example, using `/plan` in {% data variables.copilot.copilot_cli_short %} counts as one premium request, and any follow-up prompt you send counts as another. ## What are premium requests? diff --git a/content/integrations/concepts/github-developer-program.md b/content/integrations/concepts/github-developer-program.md index d9836abe2e41..24157536d911 100644 --- a/content/integrations/concepts/github-developer-program.md +++ b/content/integrations/concepts/github-developer-program.md @@ -20,10 +20,6 @@ Building an application that integrates with {% data variables.product.github %} Build your own tools that seamlessly integrate with {% data variables.product.github %} APIs. For more information, see [AUTOTITLE](/rest/about-the-rest-api/comparing-githubs-rest-api-and-graphql-api). -## Take on the enterprise - -Email partnerships@github.com to request developer licenses to build and test your application against {% data variables.product.prodname_ghe_server %}. - ## Have an integration that works with GitHub? Awesome! Here’s how you can spread the word: diff --git a/content/organizations/managing-peoples-access-to-your-organization-with-roles/adding-a-billing-manager-to-your-organization.md b/content/organizations/managing-peoples-access-to-your-organization-with-roles/adding-a-billing-manager-to-your-organization.md index 1d5300c2169f..f9cdd9c6f440 100644 --- a/content/organizations/managing-peoples-access-to-your-organization-with-roles/adding-a-billing-manager-to-your-organization.md +++ b/content/organizations/managing-peoples-access-to-your-organization-with-roles/adding-a-billing-manager-to-your-organization.md @@ -21,12 +21,7 @@ Members of your organization's Owners team can give _billing manager_ permission Billing managers can: -* Upgrade or downgrade between {% data variables.product.prodname_free_user %} and {% data variables.product.prodname_team %} plans -* Add, update, or remove payment methods -* View payment history -* Download receipts -* View, invite, and remove billing managers -* Start, modify, or cancel sponsorships +{% data reusables.billing.org-billing-manager-permissions %} In addition, all billing managers will receive billing receipts by email on the organization's billing date. diff --git a/data/reusables/billing/org-billing-manager-permissions.md b/data/reusables/billing/org-billing-manager-permissions.md new file mode 100644 index 000000000000..98076c5ad871 --- /dev/null +++ b/data/reusables/billing/org-billing-manager-permissions.md @@ -0,0 +1,8 @@ +* View all metered usage for your organization and its repositories. +* View organization-level budgets. +* Download CSV usage reports. +* View payment history and download receipts. +* Add, update, or remove payment methods. +* Upgrade or downgrade between {% data variables.product.prodname_free_user %} and {% data variables.product.prodname_team %} plans. +* View, invite, and remove billing managers. +* Start, modify, or cancel sponsorships. diff --git a/next.config.ts b/next.config.ts index 8c070472000f..2d2f60df8a6d 100644 --- a/next.config.ts +++ b/next.config.ts @@ -15,6 +15,15 @@ const config: NextConfig = { // Transpile @primer/react so Next's webpack can process its CSS and other assets // This ensures CSS in node_modules/@primer/react is handled by the app's loaders. transpilePackages: ['@primer/react'], + // Keep OTel packages out of the Next.js server bundle. + // They must be loaded via native require() for auto-instrumentation to work. + serverExternalPackages: [ + '@opentelemetry/api', + '@opentelemetry/auto-instrumentations-node', + '@opentelemetry/core', + '@opentelemetry/exporter-trace-otlp-proto', + '@opentelemetry/sdk-node', + ], // speed up production `next build` by ignoring typechecking during that step of build. // type-checking still occurs in the Dockerfile build typescript: { @@ -27,13 +36,7 @@ const config: NextConfig = { }, sassOptions: { quietDeps: true, - silenceDeprecations: [ - 'legacy-js-api', - 'import', - 'global-builtin', - 'color-4-api', - 'mixed-decls', - ], + silenceDeprecations: ['legacy-js-api', 'import', 'global-builtin', 'color-4-api'], }, // Don't use automatic Next.js logging in dev unless the log level is `debug` or higher // See `src/observability/logger/README.md` for log levels @@ -48,8 +51,15 @@ const config: NextConfig = { }) }, - webpack: (webpackConfig) => { + webpack: (webpackConfig, { isServer }) => { webpackConfig.resolve.fallback = { fs: false, async_hooks: false } + // OTel is server-only. Alias to empty stub in browser bundles. + if (!isServer) { + webpackConfig.resolve.alias = { + ...webpackConfig.resolve.alias, + '@/observability/lib/tracing': path.resolve('./src/observability/lib/tracing.browser.ts'), + } + } return webpackConfig }, @@ -71,6 +81,9 @@ const config: NextConfig = { '@/observability/logger/lib/logger-context': { browser: './empty.ts', }, + '@/observability/lib/tracing': { + browser: './src/observability/lib/tracing.browser.ts', + }, }, }, diff --git a/package-lock.json b/package-lock.json index fc8af8a5b991..c98ae0e2012c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,6 +15,11 @@ "@octokit/graphql": "9.0.1", "@octokit/plugin-retry": "8.0.1", "@octokit/request-error": "7.0.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/auto-instrumentations-node": "^0.69.0", + "@opentelemetry/core": "^2.5.1", + "@opentelemetry/exporter-trace-otlp-proto": "^0.212.0", + "@opentelemetry/sdk-node": "^0.212.0", "@primer/behaviors": "^1.10.2", "@primer/css": "^21.3.1", "@primer/live-region-element": "^0.7.2", @@ -1709,6 +1714,61 @@ "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, + "node_modules/@grpc/grpc-js": { + "version": "1.14.3", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.3.tgz", + "integrity": "sha512-Iq8QQQ/7X3Sac15oB6p0FmUg/klxQvXLeileoqrTRGJYLV+/9tubbr9ipz0GKHjmXVsgFPo/+W+2cA8eNcR+XA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/proto-loader": "^0.8.0", + "@js-sdsl/ordered-map": "^4.4.2" + }, + "engines": { + "node": ">=12.10.0" + } + }, + "node_modules/@grpc/proto-loader": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.0.tgz", + "integrity": "sha512-rc1hOQtjIWGxcxpb9aHAfLpIctjEnsDehj0DAiVfBlmT84uvR0uUtN2hEi/ecvWVjXUGf5qPF4qEgiLOx1YIMQ==", + "license": "Apache-2.0", + "dependencies": { + "lodash.camelcase": "^4.3.0", + "long": "^5.0.0", + "protobufjs": "^7.5.3", + "yargs": "^17.7.2" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@grpc/proto-loader/node_modules/protobufjs": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.4.tgz", + "integrity": "sha512-CvexbZtbov6jW2eXAvLukXjXUW1TzFaivC46BpWc/3BpcCysb5Vffu+B3XHMm8lVEuy2Mm4XGex8hBSg1yapPg==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@hapi/address": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/@hapi/address/-/address-5.1.1.tgz", @@ -2305,6 +2365,16 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@js-sdsl/ordered-map": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz", + "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, "node_modules/@lit-labs/react": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/@lit-labs/react/-/react-1.2.1.tgz", @@ -2837,7 +2907,99 @@ "node": ">=8.0.0" } }, - "node_modules/@opentelemetry/core": { + "node_modules/@opentelemetry/api-logs": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.211.0.tgz", + "integrity": "sha512-swFdZq8MCdmdR22jTVGQDhwqDzcI4M10nhjXkLr1EsIzXgZBqm4ZlmmcWsg3TSNf+3mzgOiqveXmBLZuDi2Lgg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node": { + "version": "0.69.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/auto-instrumentations-node/-/auto-instrumentations-node-0.69.0.tgz", + "integrity": "sha512-m/wqAaeZi3VkT2izPRivEfZrvKR+cP7Y/Jkic9D8QClGFpfd3bgvfUZS+OA2MzL+RT46sO27G5TKPN+M35xQJg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/instrumentation-amqplib": "^0.58.0", + "@opentelemetry/instrumentation-aws-lambda": "^0.63.0", + "@opentelemetry/instrumentation-aws-sdk": "^0.66.0", + "@opentelemetry/instrumentation-bunyan": "^0.56.0", + "@opentelemetry/instrumentation-cassandra-driver": "^0.56.0", + "@opentelemetry/instrumentation-connect": "^0.54.0", + "@opentelemetry/instrumentation-cucumber": "^0.26.0", + "@opentelemetry/instrumentation-dataloader": "^0.28.0", + "@opentelemetry/instrumentation-dns": "^0.54.0", + "@opentelemetry/instrumentation-express": "^0.59.0", + "@opentelemetry/instrumentation-fastify": "^0.55.0", + "@opentelemetry/instrumentation-fs": "^0.30.0", + "@opentelemetry/instrumentation-generic-pool": "^0.54.0", + "@opentelemetry/instrumentation-graphql": "^0.58.0", + "@opentelemetry/instrumentation-grpc": "^0.211.0", + "@opentelemetry/instrumentation-hapi": "^0.57.0", + "@opentelemetry/instrumentation-http": "^0.211.0", + "@opentelemetry/instrumentation-ioredis": "^0.59.0", + "@opentelemetry/instrumentation-kafkajs": "^0.20.0", + "@opentelemetry/instrumentation-knex": "^0.55.0", + "@opentelemetry/instrumentation-koa": "^0.59.0", + "@opentelemetry/instrumentation-lru-memoizer": "^0.55.0", + "@opentelemetry/instrumentation-memcached": "^0.54.0", + "@opentelemetry/instrumentation-mongodb": "^0.64.0", + "@opentelemetry/instrumentation-mongoose": "^0.57.0", + "@opentelemetry/instrumentation-mysql": "^0.57.0", + "@opentelemetry/instrumentation-mysql2": "^0.57.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.57.0", + "@opentelemetry/instrumentation-net": "^0.55.0", + "@opentelemetry/instrumentation-openai": "^0.9.0", + "@opentelemetry/instrumentation-oracledb": "^0.36.0", + "@opentelemetry/instrumentation-pg": "^0.63.0", + "@opentelemetry/instrumentation-pino": "^0.57.0", + "@opentelemetry/instrumentation-redis": "^0.59.0", + "@opentelemetry/instrumentation-restify": "^0.56.0", + "@opentelemetry/instrumentation-router": "^0.55.0", + "@opentelemetry/instrumentation-runtime-node": "^0.24.0", + "@opentelemetry/instrumentation-socket.io": "^0.57.0", + "@opentelemetry/instrumentation-tedious": "^0.30.0", + "@opentelemetry/instrumentation-undici": "^0.21.0", + "@opentelemetry/instrumentation-winston": "^0.55.0", + "@opentelemetry/resource-detector-alibaba-cloud": "^0.33.1", + "@opentelemetry/resource-detector-aws": "^2.11.0", + "@opentelemetry/resource-detector-azure": "^0.19.0", + "@opentelemetry/resource-detector-container": "^0.8.2", + "@opentelemetry/resource-detector-gcp": "^0.46.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/sdk-node": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.4.1", + "@opentelemetry/core": "^2.0.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/configuration": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/configuration/-/configuration-0.211.0.tgz", + "integrity": "sha512-PNsCkzsYQKyv8wiUIsH+loC4RYyblOaDnVASBtKS22hK55ToWs2UP6IsrcfSWWn54wWTvVe2gnfwz67Pvrxf2Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "yaml": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/configuration/node_modules/@opentelemetry/core": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", @@ -2852,186 +3014,2547 @@ "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@opentelemetry/semantic-conventions": { - "version": "1.39.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", - "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/context-async-hooks": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.5.0.tgz", + "integrity": "sha512-uOXpVX0ZjO7heSVjhheW2XEPrhQAWr2BScDPoZ9UDycl5iuHG+Usyc3AIfG6kZeC1GyLpMInpQ6X5+9n69yOFw==", "license": "Apache-2.0", "engines": { - "node": ">=14" + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@parcel/watcher": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", - "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-logs-otlp-grpc": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.211.0.tgz", + "integrity": "sha512-UhOoWENNqyaAMP/dL1YXLkXt6ZBtovkDDs1p4rxto9YwJX1+wMjwg+Obfyg2kwpcMoaiIFT3KQIcLNW8nNGNfQ==", + "license": "Apache-2.0", "dependencies": { - "detect-libc": "^1.0.3", - "is-glob": "^4.0.3", - "micromatch": "^4.0.5", - "node-addon-api": "^7.0.0" + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/sdk-logs": "0.211.0" }, "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "node": "^18.19.0 || >=20.6.0" }, - "optionalDependencies": { - "@parcel/watcher-android-arm64": "2.5.1", - "@parcel/watcher-darwin-arm64": "2.5.1", - "@parcel/watcher-darwin-x64": "2.5.1", - "@parcel/watcher-freebsd-x64": "2.5.1", - "@parcel/watcher-linux-arm-glibc": "2.5.1", - "@parcel/watcher-linux-arm-musl": "2.5.1", - "@parcel/watcher-linux-arm64-glibc": "2.5.1", - "@parcel/watcher-linux-arm64-musl": "2.5.1", - "@parcel/watcher-linux-x64-glibc": "2.5.1", - "@parcel/watcher-linux-x64-musl": "2.5.1", - "@parcel/watcher-win32-arm64": "2.5.1", - "@parcel/watcher-win32-ia32": "2.5.1", - "@parcel/watcher-win32-x64": "2.5.1" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@parcel/watcher-android-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", - "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-logs-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, "engines": { - "node": ">= 10.0.0" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", - "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-logs-otlp-http": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.211.0.tgz", + "integrity": "sha512-c118Awf1kZirHkqxdcF+rF5qqWwNjJh+BB1CmQvN9AQHC/DUIldy6dIkJn3EKlQnQ3HmuNRKc/nHHt5IusN7mA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/sdk-logs": "0.211.0" + }, "engines": { - "node": ">= 10.0.0" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", - "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-logs-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, "engines": { - "node": ">= 10.0.0" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", - "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-logs-otlp-proto": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.211.0.tgz", + "integrity": "sha512-kMvfKMtY5vJDXeLnwhrZMEwhZ2PN8sROXmzacFU/Fnl4Z79CMrOaL7OE+5X3SObRYlDUa7zVqaXp9ZetYCxfDQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-logs": "0.211.0", + "@opentelemetry/sdk-trace-base": "2.5.0" + }, "engines": { - "node": ">= 10.0.0" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", - "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-logs-otlp-proto/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, "engines": { - "node": ">= 10.0.0" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" } }, - "node_modules/@parcel/watcher-linux-arm-musl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", - "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.211.0.tgz", + "integrity": "sha512-D/U3G8L4PzZp8ot5hX9wpgbTymgtLZCiwR7heMe4LsbGV4OdctS1nfyvaQHLT6CiGZ6FjKc1Vk9s6kbo9SWLXQ==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.211.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-metrics": "2.5.0" + }, "engines": { - "node": ">= 10.0.0" + "node": "^18.19.0 || >=20.6.0" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" } }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", - "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", - "cpu": [ - "arm64" - ], - "dev": true, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-metrics-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.211.0.tgz", + "integrity": "sha512-lfHXElPAoDSPpPO59DJdN5FLUnwi1wxluLTWQDayqrSPfWRnluzxRhD+g7rF8wbj1qCz0sdqABl//ug1IZyWvA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-metrics": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.211.0.tgz", + "integrity": "sha512-61iNbffEpyZv/abHaz3BQM3zUtA2kVIDBM+0dS9RK68ML0QFLRGYa50xVMn2PYMToyfszEPEgFC3ypGae2z8FA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.211.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-metrics": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-metrics-otlp-proto/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-prometheus": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.211.0.tgz", + "integrity": "sha512-cD0WleEL3TPqJbvxwz5MVdVJ82H8jl8mvMad4bNU24cB5SH2mRW5aMLDTuV4614ll46R//R3RMmci26mc2L99g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-metrics": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-prometheus/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.211.0.tgz", + "integrity": "sha512-eFwx4Gvu6LaEiE1rOd4ypgAiWEdZu7Qzm2QNN2nJqPW1XDeAVH1eNwVcVQl+QK9HR/JCDZ78PZgD7xD/DBDqbw==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.211.0.tgz", + "integrity": "sha512-F1Rv3JeMkgS//xdVjbQMrI3+26e5SXC7vXA6trx8SWEA0OUhw4JHB+qeHtH0fJn46eFItrYbL5m8j4qi9Sfaxw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.211.0.tgz", + "integrity": "sha512-DkjXwbPiqpcPlycUojzG2RmR0/SIK8Gi9qWO9znNvSqgzrnAIE9x2n6yPfpZ+kWHZGafvsvA1lVXucTyyQa5Kg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-zipkin": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.5.0.tgz", + "integrity": "sha512-bk9VJgFgUAzkZzU8ZyXBSWiUGLOM3mZEgKJ1+jsZclhRnAoDNf+YBdq+G9R3cP0+TKjjWad+vVrY/bE/vRR9lA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.211.0.tgz", + "integrity": "sha512-bp1+63V8WPV+bRI9EQG6E9YID1LIHYSZVbp7f+44g9tRzCq+rtw/o4fpL5PC31adcUsFiz/oN0MdLISSrZDdrg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-transformer": "0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/otlp-exporter-base/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.211.0.tgz", + "integrity": "sha512-mR5X+N4SuphJeb7/K7y0JNMC8N1mB6gEtjyTLv+TSAhl0ZxNQzpSKP8S5Opk90fhAqVYD4R0SQSAirEBlH1KSA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.7.1", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/otlp-exporter-base": "0.211.0", + "@opentelemetry/otlp-transformer": "0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/otlp-grpc-exporter-base/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/otlp-transformer": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.211.0.tgz", + "integrity": "sha512-julhCJ9dXwkOg9svuuYqqjXLhVaUgyUvO2hWbTxwjvLXX2rG3VtAaB0SzxMnGTuoCZizBT7Xqqm2V7+ggrfCXA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-logs": "0.211.0", + "@opentelemetry/sdk-metrics": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0", + "protobufjs": "8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/propagator-b3": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-2.5.0.tgz", + "integrity": "sha512-g10m4KD73RjHrSvUge+sUxUl8m4VlgnGc6OKvo68a4uMfaLjdFU+AULfvMQE/APq38k92oGUxEzBsAZ8RN/YHg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/propagator-jaeger": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.5.0.tgz", + "integrity": "sha512-t70ErZCncAR/zz5AcGkL0TF25mJiK1FfDPEQCgreyAHZ+mRJ/bNUiCnImIBDlP3mSDXy6N09DbUEKq0ktW98Hg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/resources": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.0.tgz", + "integrity": "sha512-F8W52ApePshpoSrfsSk1H2yJn9aKjCrbpQF1M9Qii0GHzbfVeFUB+rc3X4aggyZD8x9Gu3Slua+s6krmq6Dt8g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/resources/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-logs": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.211.0.tgz", + "integrity": "sha512-O5nPwzgg2JHzo59kpQTPUOTzFi0Nv5LxryG27QoXBciX3zWM3z83g+SNOHhiQVYRWFSxoWn1JM2TGD5iNjOwdA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-metrics": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.0.tgz", + "integrity": "sha512-BeJLtU+f5Gf905cJX9vXFQorAr6TAfK3SPvTFqP+scfIpDQEJfRaGJWta7sJgP+m4dNtBf9y3yvBKVAZZtJQVA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-node": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.211.0.tgz", + "integrity": "sha512-+s1eGjoqmPCMptNxcJJD4IxbWJKNLOQFNKhpwkzi2gLkEbCj6LzSHJNhPcLeBrBlBLtlSpibM+FuS7fjZ8SSFQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "@opentelemetry/configuration": "0.211.0", + "@opentelemetry/context-async-hooks": "2.5.0", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/exporter-logs-otlp-grpc": "0.211.0", + "@opentelemetry/exporter-logs-otlp-http": "0.211.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.211.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.211.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.211.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.211.0", + "@opentelemetry/exporter-prometheus": "0.211.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.211.0", + "@opentelemetry/exporter-trace-otlp-http": "0.211.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.211.0", + "@opentelemetry/exporter-zipkin": "2.5.0", + "@opentelemetry/instrumentation": "0.211.0", + "@opentelemetry/propagator-b3": "2.5.0", + "@opentelemetry/propagator-jaeger": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/sdk-logs": "0.211.0", + "@opentelemetry/sdk-metrics": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0", + "@opentelemetry/sdk-trace-node": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.5.0.tgz", + "integrity": "sha512-VzRf8LzotASEyNDUxTdaJ9IRJ1/h692WyArDBInf5puLCjxbICD6XkHgpuudis56EndyS7LYFmtTMny6UABNdQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/resources": "2.5.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.5.0.tgz", + "integrity": "sha512-O6N/ejzburFm2C84aKNrwJVPpt6HSTSq8T0ZUMq3xT2XmqT4cwxUItcL5UWGThYuq8RTcbH8u1sfj6dmRci0Ow==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.5.0", + "@opentelemetry/core": "2.5.0", + "@opentelemetry/sdk-trace-base": "2.5.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/auto-instrumentations-node/node_modules/@opentelemetry/sdk-trace-node/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/configuration": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/configuration/-/configuration-0.212.0.tgz", + "integrity": "sha512-D8sAY6RbqMa1W8lCeiaSL2eMCW2MF87QI3y+I6DQE1j+5GrDMwiKPLdzpa/2/+Zl9v1//74LmooCTCJBvWR8Iw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "yaml": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-2.5.1.tgz", + "integrity": "sha512-MHbu8XxCHcBn6RwvCt2Vpn1WnLMNECfNKYB14LI5XypcgH4IE0/DiVifVR9tAkwPMyLXN8dOoPJfya3IryLQVw==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/core": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.1.tgz", + "integrity": "sha512-Dwlc+3HAZqpgTYq0MUyZABjFkcrKTePwuiFVLjahGD8cx3enqihmpAmdgNFO1R4m/sIe5afjJrA25Prqy4NXlA==", + "license": "Apache-2.0", + "peer": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-grpc": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-grpc/-/exporter-logs-otlp-grpc-0.212.0.tgz", + "integrity": "sha512-/0bk6fQG+eSFZ4L6NlckGTgUous/ib5+OVdg0x4OdwYeHzV3lTEo3it1HgnPY6UKpmX7ki+hJvxjsOql8rCeZA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.14.3", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/sdk-logs": "0.212.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-http": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-http/-/exporter-logs-otlp-http-0.212.0.tgz", + "integrity": "sha512-JidJasLwG/7M9RTxV/64xotDKmFAUSBc9SNlxI32QYuUMK5rVKhHNWMPDzC7E0pCAL3cu+FyiKvsTwLi2KqPYw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.212.0", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/sdk-logs": "0.212.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-http/node_modules/@opentelemetry/api-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-proto": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-logs-otlp-proto/-/exporter-logs-otlp-proto-0.212.0.tgz", + "integrity": "sha512-RpKB5UVfxc7c6Ta1UaCrxXDTQ0OD7BCGT66a97Q5zR1x3+9fw4dSaiqMXT/6FAWj2HyFbem6Rcu1UzPZikGTWQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.212.0", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-logs": "0.212.0", + "@opentelemetry/sdk-trace-base": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-proto/node_modules/@opentelemetry/api-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/exporter-logs-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.212.0.tgz", + "integrity": "sha512-/6Gqf9wpBq22XsomR1i0iPGnbQtCq2Vwnrq5oiDPjYSqveBdK1jtQbhGfmpK2mLLxk4cPDtD1ZEYdIou5K8EaA==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.14.3", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/exporter-metrics-otlp-http": "0.212.0", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-metrics": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.212.0.tgz", + "integrity": "sha512-8hgBw3aTTRpSTkU4b9MLf/2YVLnfWp+hfnLq/1Fa2cky+vx6HqTodo+Zv1GTIrAKMOOwgysOjufy0gTxngqeBg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-metrics": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-proto/-/exporter-metrics-otlp-proto-0.212.0.tgz", + "integrity": "sha512-C7I4WN+ghn3g7SnxXm2RK3/sRD0k/BYcXaK6lGU3yPjiM7a1M25MLuM6zY3PeVPPzzTZPfuS7+wgn/tHk768Xw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/exporter-metrics-otlp-http": "0.212.0", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-metrics": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-prometheus/-/exporter-prometheus-0.212.0.tgz", + "integrity": "sha512-hJFLhCJba5MW5QHexZMHZdMhBfNqNItxOsN0AZojwD1W2kU9xM+BEICowFGJFo/vNV+I2BJvTtmuKafeDSAo7Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-metrics": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-prometheus/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.212.0.tgz", + "integrity": "sha512-9xTuYWp8ClBhljDGAoa0NSsJcsxJsC9zCFKMSZJp1Osb9pjXCMRdA6fwXtlubyqe7w8FH16EWtQNKx/FWi+Ghw==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.14.3", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-grpc/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-http/-/exporter-trace-otlp-http-0.212.0.tgz", + "integrity": "sha512-v/0wMozNoiEPRolzC4YoPo4rAT0q8r7aqdnRw3Nu7IDN0CGFzNQazkfAlBJ6N5y0FYJkban7Aw5WnN73//6YlA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-http/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-proto/-/exporter-trace-otlp-proto-0.212.0.tgz", + "integrity": "sha512-d1ivqPT0V+i0IVOOdzGaLqonjtlk5jYrW7ItutWzXL/Mk+PiYb59dymy/i2reot9dDnBFWfrsvxyqdutGF5Vig==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/exporter-trace-otlp-proto/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-zipkin/-/exporter-zipkin-2.5.1.tgz", + "integrity": "sha512-Me6JVO7WqXGXsgr4+7o+B7qwKJQbt0c8WamFnxpkR43avgG9k/niTntwCaXiXUTjonWy0+61ZuX6CGzj9nn8CQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-zipkin/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.211.0.tgz", + "integrity": "sha512-h0nrZEC/zvI994nhg7EgQ8URIHt0uDTwN90r3qQUdZORS455bbx+YebnGeEuFghUT0HlJSrLF4iHw67f+odY+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.211.0", + "import-in-the-middle": "^2.0.0", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-amqplib": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-amqplib/-/instrumentation-amqplib-0.58.0.tgz", + "integrity": "sha512-fjpQtH18J6GxzUZ+cwNhWUpb71u+DzT7rFkg5pLssDGaEber91Y2WNGdpVpwGivfEluMlNMZumzjEqfg8DeKXQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-lambda": { + "version": "0.63.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-lambda/-/instrumentation-aws-lambda-0.63.0.tgz", + "integrity": "sha512-XEkXvrBtIKPgp6kFSuNV3FpugGiLIz3zpjXu/7t9ioBKN7pZG5hef3VCPUhtyE8UZ3N3D9rkjSLaDOND0inNrg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/aws-lambda": "^8.10.155" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-aws-sdk": { + "version": "0.66.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-aws-sdk/-/instrumentation-aws-sdk-0.66.0.tgz", + "integrity": "sha512-K+vFDsD0RsjxjCOWGOKgaqOoE5wxIPMA8wnGJ0no3m7MjVdpkS/dNOGUx2nYegpqZzU/jZ0qvc+JrfkvkzcUyg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.34.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-bunyan": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-bunyan/-/instrumentation-bunyan-0.56.0.tgz", + "integrity": "sha512-cTt3gLGxBvgjgUTBeMz6MaFAHXFQM/N3411mZFTzlczuOQTlsuJTn+fWTah/a0el9NsepO5LdbULRBNmA9rSUw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.211.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@types/bunyan": "1.8.11" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-cassandra-driver": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cassandra-driver/-/instrumentation-cassandra-driver-0.56.0.tgz", + "integrity": "sha512-56Yd41E15QlciuqC6DZR2KdeetXzhdcwp1BRRb8ORsHbRQWbvPdhV8vpvkrvs3cvY8N1KoqtPgh7mdkVhyQz+Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.37.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-connect": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-connect/-/instrumentation-connect-0.54.0.tgz", + "integrity": "sha512-43RmbhUhqt3uuPnc16cX6NsxEASEtn8z/cYV8Zpt6EP4p2h9s4FNuJ4Q9BbEQ2C0YlCCB/2crO1ruVz/hWt8fA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0", + "@types/connect": "3.4.38" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-cucumber": { + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-cucumber/-/instrumentation-cucumber-0.26.0.tgz", + "integrity": "sha512-LGSgNR9gMJ3eiChbW9WjFgiCdJwdPKwARZwRE1s57CGY8/B3emAoQt2B05TY1y2TQuQKRBFbyNVXpWHFl9WQGQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dataloader": { + "version": "0.28.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dataloader/-/instrumentation-dataloader-0.28.0.tgz", + "integrity": "sha512-ExXGBp0sUj8yhm6Znhf9jmuOaGDsYfDES3gswZnKr4MCqoBWQdEFn6EoDdt5u+RdbxQER+t43FoUihEfTSqsjA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-dns": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-dns/-/instrumentation-dns-0.54.0.tgz", + "integrity": "sha512-CvnGlYr8FKB2SeqauqJ7bSgZhrkVYj1vgbqFcbc/wnQcc03jc+afngkduahHiBgnJr+CYL/p3XjdKWp7AKYoGg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-express": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-express/-/instrumentation-express-0.59.0.tgz", + "integrity": "sha512-pMKV/qnHiW/Q6pmbKkxt0eIhuNEtvJ7sUAyee192HErlr+a1Jx+FZ3WjfmzhQL1geewyGEiPGkmjjAgNY8TgDA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fastify": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fastify/-/instrumentation-fastify-0.55.0.tgz", + "integrity": "sha512-kkx8ODI57dN+mMW+nPuE9gniSXs/LlxWiPoXXiAJhtQJPpMqQwncHlMo+1c+qzQC5aQWkKdDskJG7TPnACNgcw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-fs": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.30.0.tgz", + "integrity": "sha512-n3Cf8YhG7reaj5dncGlRIU7iT40bxPOjsBEA5Bc1a1g6e9Qvb+JFJ7SEiMlPbUw4PBmxE3h40ltE8LZ3zVt6OA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-generic-pool": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-generic-pool/-/instrumentation-generic-pool-0.54.0.tgz", + "integrity": "sha512-8dXMBzzmEdXfH/wjuRvcJnUFeWzZHUnExkmFJ2uPfa31wmpyBCMxO59yr8f/OXXgSogNgi/uPo9KW9H7LMIZ+g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-graphql": { + "version": "0.58.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.58.0.tgz", + "integrity": "sha512-+yWVVY7fxOs3j2RixCbvue8vUuJ1inHxN2q1sduqDB0Wnkr4vOzVKRYl/Zy7B31/dcPS72D9lo/kltdOTBM3bQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-grpc": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-grpc/-/instrumentation-grpc-0.211.0.tgz", + "integrity": "sha512-bshedE3TaD18OE3oPU15j8bn4vz+3X5mvg9jluoSn/ZjlshCb1FrstjNkTYQuRERWzeMl7WcR8sShr91FcUBXA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "0.211.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-hapi": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.57.0.tgz", + "integrity": "sha512-Os4THbvls8cTQTVA8ApLfZZztuuqGEeqog0XUnyRW7QVF0d/vOVBEcBCk1pazPFmllXGEdNbbat8e2fYIWdFbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http": { + "version": "0.211.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-http/-/instrumentation-http-0.211.0.tgz", + "integrity": "sha512-n0IaQ6oVll9PP84SjbOCwDjaJasWRHi6BLsbMLiT6tNj7QbVOkuA5sk/EfZczwI0j5uTKl1awQPivO/ldVtsqA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.0", + "@opentelemetry/instrumentation": "0.211.0", + "@opentelemetry/semantic-conventions": "^1.29.0", + "forwarded-parse": "2.1.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-http/node_modules/@opentelemetry/core": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.5.0.tgz", + "integrity": "sha512-ka4H8OM6+DlUhSAZpONu0cPBtPPTQKxbxVzC4CzVx5+K4JnroJVBtDzLAMx4/3CDTJXRvVFhpFjtl4SaiTNoyQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/instrumentation-ioredis": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-ioredis/-/instrumentation-ioredis-0.59.0.tgz", + "integrity": "sha512-875UxzBHWkW+P4Y45SoFM2AR8f8TzBMD8eO7QXGCyFSCUMP5s9vtt/BS8b/r2kqLyaRPK6mLbdnZznK3XzQWvw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-kafkajs": { + "version": "0.20.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-kafkajs/-/instrumentation-kafkajs-0.20.0.tgz", + "integrity": "sha512-yJXOuWZROzj7WmYCUiyT27tIfqBrVtl1/TwVbQyWPz7rL0r1Lu7kWjD0PiVeTCIL6CrIZ7M2s8eBxsTAOxbNvw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-knex": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-knex/-/instrumentation-knex-0.55.0.tgz", + "integrity": "sha512-FtTL5DUx5Ka/8VK6P1VwnlUXPa3nrb7REvm5ddLUIeXXq4tb9pKd+/ThB1xM/IjefkRSN3z8a5t7epYw1JLBJQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-koa": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-koa/-/instrumentation-koa-0.59.0.tgz", + "integrity": "sha512-K9o2skADV20Skdu5tG2bogPKiSpXh4KxfLjz6FuqIVvDJNibwSdu5UvyyBzRVp1rQMV6UmoIk6d3PyPtJbaGSg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.9.0" + } + }, + "node_modules/@opentelemetry/instrumentation-lru-memoizer": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-lru-memoizer/-/instrumentation-lru-memoizer-0.55.0.tgz", + "integrity": "sha512-FDBfT7yDGcspN0Cxbu/k8A0Pp1Jhv/m7BMTzXGpcb8ENl3tDj/51U65R5lWzUH15GaZA15HQ5A5wtafklxYj7g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-memcached": { + "version": "0.54.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-memcached/-/instrumentation-memcached-0.54.0.tgz", + "integrity": "sha512-7lG+XMQVt8I+/qc4U0KAwabnIAn4CubmxBPftlrChmcok6wbv6z6W+SCVNBbN13FvPgum8NO0YwyuUXMmCyXvg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/memcached": "^2.2.6" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongodb": { + "version": "0.64.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.64.0.tgz", + "integrity": "sha512-pFlCJjweTqVp7B220mCvCld1c1eYKZfQt1p3bxSbcReypKLJTwat+wbL2YZoX9jPi5X2O8tTKFEOahO5ehQGsA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mongoose": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongoose/-/instrumentation-mongoose-0.57.0.tgz", + "integrity": "sha512-MthiekrU/BAJc5JZoZeJmo0OTX6ycJMiP6sMOSRTkvz5BrPMYDqaJos0OgsLPL/HpcgHP7eo5pduETuLguOqcg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql/-/instrumentation-mysql-0.57.0.tgz", + "integrity": "sha512-HFS/+FcZ6Q7piM7Il7CzQ4VHhJvGMJWjx7EgCkP5AnTntSN5rb5Xi3TkYJHBKeR27A0QqPlGaCITi93fUDs++Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/mysql": "2.15.27" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-mysql2": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mysql2/-/instrumentation-mysql2-0.57.0.tgz", + "integrity": "sha512-nHSrYAwF7+aV1E1V9yOOP9TchOodb6fjn4gFvdrdQXiRE7cMuffyLLbCZlZd4wsspBzVwOXX8mpURdRserAhNA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@opentelemetry/sql-common": "^0.41.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-nestjs-core": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-nestjs-core/-/instrumentation-nestjs-core-0.57.0.tgz", + "integrity": "sha512-mzTjjethjuk70o/vWUeV12QwMG9EAFJpkn13/q8zi++sNosf2hoGXTplIdbs81U8S3PJ4GxHKsBjM0bj1CGZ0g==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.30.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-net": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-net/-/instrumentation-net-0.55.0.tgz", + "integrity": "sha512-J7isLTAmBphAKX99fZgR/jYFRJk+d5E3yVDEd7eTcyPPwFDN/LM8J8j/H5gP4ukZCbt0mtKnx1CA+P5+qw7xFQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-openai": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-openai/-/instrumentation-openai-0.9.0.tgz", + "integrity": "sha512-Tf3shDZZo3pKz0LBschaEfX+SgpwMITnm8moOMzr6Fc10sKU96GxFwMmEg2JC0JW5x56kGJuwRoXZCVL66GBgg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.211.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.36.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-oracledb": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-oracledb/-/instrumentation-oracledb-0.36.0.tgz", + "integrity": "sha512-VyfdaRfr/xnx/ndQnCCk34z7HqADxmRi47SLTzL9m79LrA+F1qK49nCcqbeiFfeVJ2RA5NmfSS+BllFE4RGnsw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@types/oracledb": "6.5.2" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.63.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.63.0.tgz", + "integrity": "sha512-dKm/ODNN3GgIQVlbD6ZPxwRc3kleLf95hrRWXM+l8wYo+vSeXtEpQPT53afEf6VFWDVzJK55VGn8KMLtSve/cg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.34.0", + "@opentelemetry/sql-common": "^0.41.2", + "@types/pg": "8.15.6", + "@types/pg-pool": "2.0.7" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-pino": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pino/-/instrumentation-pino-0.57.0.tgz", + "integrity": "sha512-Oa+PT1fxWQo88KSfibLJSyCwdV9Kb2iqjpIbfMK5CFcyeOGfth8mVSFjvQEaCo+Tdbpq9Y8Ylyi4/XmWrxStew==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.211.0", + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-redis": { + "version": "0.59.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-redis/-/instrumentation-redis-0.59.0.tgz", + "integrity": "sha512-JKv1KDDYA2chJ1PC3pLP+Q9ISMQk6h5ey+99mB57/ARk0vQPGZTTEb4h4/JlcEpy7AYT8HIGv7X6l+br03Neeg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/redis-common": "^0.38.2", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-restify": { + "version": "0.56.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-restify/-/instrumentation-restify-0.56.0.tgz", + "integrity": "sha512-ZkPT7zoIx6du3u7Js4n7FEw1FvNdeIpprpcM0pR4p7kfgQ82ZzhfJ7ilWKxT9Hpe6HMu+yFLicFyS1b83XcVMQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-router": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-router/-/instrumentation-router-0.55.0.tgz", + "integrity": "sha512-8IA64a6+vVQavH1qj2W/0mPOr1uS6ROkLoV29p+3At2omEIgn13g46yslKqU5lIgMSn9uzU4tSlOTe6vQM4dIg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-runtime-node": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-runtime-node/-/instrumentation-runtime-node-0.24.0.tgz", + "integrity": "sha512-1gNjTpHhgHIkRXivY4Nk+jS+2oChwQSnEVne4AHvlY0tzLHpWE+LEZV6DoiN7Ui93/UpnebhMsF0YUnFZaeJdg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-socket.io": { + "version": "0.57.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-socket.io/-/instrumentation-socket.io-0.57.0.tgz", + "integrity": "sha512-0FhO9/UPnOsRbbVHLxgffXMEdATNJQauwM+X4+X6UaV9EANEhci+etMX9R06xprJRvE3kDcfXoMn2MTF3RdNDw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-tedious": { + "version": "0.30.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-tedious/-/instrumentation-tedious-0.30.0.tgz", + "integrity": "sha512-bZy9Q8jFdycKQ2pAsyuHYUHNmCxCOGdG6eg1Mn75RvQDccq832sU5OWOBnc12EFUELI6icJkhR7+EQKMBam2GA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.33.0", + "@types/tedious": "^4.0.14" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/instrumentation-undici": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-undici/-/instrumentation-undici-0.21.0.tgz", + "integrity": "sha512-gok0LPUOTz2FQ1YJMZzaHcOzDFyT64XJ8M9rNkugk923/p6lDGms/cRW1cqgqp6N6qcd6K6YdVHwPEhnx9BWbw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/instrumentation": "^0.211.0", + "@opentelemetry/semantic-conventions": "^1.24.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.7.0" + } + }, + "node_modules/@opentelemetry/instrumentation-winston": { + "version": "0.55.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-winston/-/instrumentation-winston-0.55.0.tgz", + "integrity": "sha512-RKW/PYJrvIbRYss0uKe0eU+FgIRScnQTJXIWAZK17ViHf7EALaRDXOu3tFW5JDRg6fkccj5q90YZUCzh6s0v5A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "^0.211.0", + "@opentelemetry/instrumentation": "^0.211.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-exporter-base": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.212.0.tgz", + "integrity": "sha512-HoMv5pQlzbuxiMS0hN7oiUtg8RsJR5T7EhZccumIWxYfNo/f4wFc7LPDfFK6oHdG2JF/+qTocfqIHoom+7kLpw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-transformer": "0.212.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-grpc-exporter-base": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-grpc-exporter-base/-/otlp-grpc-exporter-base-0.212.0.tgz", + "integrity": "sha512-YidOSlzpsun9uw0iyIWrQp6HxpMtBlECE3tiHGAsnpEqJWbAUWcMnIffvIuvTtTQ1OyRtwwaE79dWSQ8+eiB7g==", + "license": "Apache-2.0", + "dependencies": { + "@grpc/grpc-js": "^1.14.3", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/otlp-exporter-base": "0.212.0", + "@opentelemetry/otlp-transformer": "0.212.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-transformer/-/otlp-transformer-0.212.0.tgz", + "integrity": "sha512-bj7zYFOg6Db7NUwsRZQ/WoVXpAf41WY2gsd3kShSfdpZQDRKHWJiRZIg7A8HvWsf97wb05rMFzPbmSHyjEl9tw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.212.0", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-logs": "0.212.0", + "@opentelemetry/sdk-metrics": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1", + "protobufjs": "8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-2.5.1.tgz", + "integrity": "sha512-AU6sZgunZrZv/LTeHP+9IQsSSH5p3PtOfDPe8VTdwYH69nZCfvvvXehhzu+9fMW2mgJMh5RVpiH8M9xuYOu5Dg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-2.5.1.tgz", + "integrity": "sha512-8+SB94/aSIOVGDUPRFSBRHVUm2A8ye1vC6/qcf/D+TF4qat7PC6rbJhRxiUGDXZtMtKEPM/glgv5cBGSJQymSg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/redis-common": { + "version": "0.38.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/redis-common/-/redis-common-0.38.2.tgz", + "integrity": "sha512-1BCcU93iwSRZvDAgwUxC/DV4T/406SkMfxGqu5ojc3AvNI+I9GhV7v0J1HljsczuuhcnFLYqD5VmwVXfCGHzxA==", + "license": "Apache-2.0", + "engines": { + "node": "^18.19.0 || >=20.6.0" + } + }, + "node_modules/@opentelemetry/resource-detector-alibaba-cloud": { + "version": "0.33.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-alibaba-cloud/-/resource-detector-alibaba-cloud-0.33.3.tgz", + "integrity": "sha512-Ep3LDWALU+wCgGzAa1rgFXh3TObahN7HaQZntAeVQnnNhZ3VSXnBniRGeSCTIRvRr7YdZvq+G+rstixtAN5Ugw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-aws": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-aws/-/resource-detector-aws-2.13.0.tgz", + "integrity": "sha512-ZPCn7gZhGqUYUoD+RCHIlayoHBMaJaEjfqlgz2EPKoXJ4y7Ru7CUm+Tm3yJVMKF92cN9xUQR0j5KALyF0fg9aw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.27.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-azure": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-azure/-/resource-detector-azure-0.19.0.tgz", + "integrity": "sha512-3UBJYyAfQY7aqot4xBvTsGlxi9Ax5XwWlddCvFPNIfZiy5KX405w3KThcRypadVsP5Q9D/lr/WAn5J+xXTqJoA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "@opentelemetry/semantic-conventions": "^1.37.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-container": { + "version": "0.8.4", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-container/-/resource-detector-container-0.8.4.tgz", + "integrity": "sha512-kIvGHkMSacp+kb7btTuXbOAIWLyOCO+P/h/8xxaeLcp5ptmHRZ67uEdLAQo61ApdayFB/uqjJ9gY4x2/i/KsoA==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resource-detector-gcp": { + "version": "0.46.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resource-detector-gcp/-/resource-detector-gcp-0.46.0.tgz", + "integrity": "sha512-CulcNXV/a4lc4TTYFdApTfRg4DlCwiUilsXnEsRfFSK/p/EbkfgEQz8hB4tZF5z/Us9MnhtuT6l4Kj4Ng8qLcw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0", + "@opentelemetry/resources": "^2.0.0", + "gcp-metadata": "^6.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.6.0.tgz", + "integrity": "sha512-D4y/+OGe3JSuYUCBxtH5T9DSAWNcvCb/nQWIga8HNtXTVPQn59j0nTBAgaAXxUVBDl40mG3Tc76b46wPlZaiJQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.6.0", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/core": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.6.0.tgz", + "integrity": "sha512-HLM1v2cbZ4TgYN6KEOj+Bbj8rAKriOdkF9Ed3tG25FoprSiQl7kYc+RRT6fUZGOvx0oMi5U67GoFdT+XUn8zEg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-logs/-/sdk-logs-0.212.0.tgz", + "integrity": "sha512-qglb5cqTf0mOC1sDdZ7nfrPjgmAqs2OxkzOPIf2+Rqx8yKBK0pS7wRtB1xH30rqahBIut9QJDbDePyvtyqvH/Q==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.212.0", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/resources": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.4.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/api-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/sdk-logs/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-metrics/-/sdk-metrics-2.5.1.tgz", + "integrity": "sha512-RKMn3QKi8nE71ULUo0g/MBvq1N4icEBo7cQSKnL3URZT16/YH3nSVgWegOjwx7FRBTrjOIkMJkCUn/ZFIEfn4A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/resources": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.9.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.212.0.tgz", + "integrity": "sha512-tJzVDk4Lo44MdgJLlP+gdYdMnjxSNsjC/IiTxj5CFSnsjzpHXwifgl3BpUX67Ty3KcdubNVfedeBc/TlqHXwwg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.212.0", + "@opentelemetry/configuration": "0.212.0", + "@opentelemetry/context-async-hooks": "2.5.1", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/exporter-logs-otlp-grpc": "0.212.0", + "@opentelemetry/exporter-logs-otlp-http": "0.212.0", + "@opentelemetry/exporter-logs-otlp-proto": "0.212.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.212.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.212.0", + "@opentelemetry/exporter-metrics-otlp-proto": "0.212.0", + "@opentelemetry/exporter-prometheus": "0.212.0", + "@opentelemetry/exporter-trace-otlp-grpc": "0.212.0", + "@opentelemetry/exporter-trace-otlp-http": "0.212.0", + "@opentelemetry/exporter-trace-otlp-proto": "0.212.0", + "@opentelemetry/exporter-zipkin": "2.5.1", + "@opentelemetry/instrumentation": "0.212.0", + "@opentelemetry/propagator-b3": "2.5.1", + "@opentelemetry/propagator-jaeger": "2.5.1", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/sdk-logs": "0.212.0", + "@opentelemetry/sdk-metrics": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1", + "@opentelemetry/sdk-trace-node": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/api-logs": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-logs/-/api-logs-0.212.0.tgz", + "integrity": "sha512-TEEVrLbNROUkYY51sBJGk7lO/OLjuepch8+hmpM6ffMJQ2z/KVCjdHuCFX6fJj8OkJP2zckPjrJzQtXU3IAsFg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api": "^1.3.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/instrumentation": { + "version": "0.212.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.212.0.tgz", + "integrity": "sha512-IyXmpNnifNouMOe0I/gX7ENfv2ZCNdYTF0FpCsoBcpbIHzk81Ww9rQTYTnvghszCg7qGrIhNvWC8dhEifgX9Jg==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/api-logs": "0.212.0", + "import-in-the-middle": "^2.0.6", + "require-in-the-middle": "^8.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.3.0" + } + }, + "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.5.1.tgz", + "integrity": "sha512-iZH3Gw8cxQn0gjpOjJMmKLd9GIaNh/E3v3ST67vyzLSxHBs14HsG4dy7jMYyC5WXGdBVEcM7U/XTF5hCQxjDMw==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/resources": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-base/node_modules/@opentelemetry/resources": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-2.5.1.tgz", + "integrity": "sha512-BViBCdE/GuXRlp9k7nS1w6wJvY5fnFX5XvuEtWsTAOQFIO89Eru7lGW3WbfbxtCuZ/GbrJfAziXG0w0dpxL7eQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "2.5.1", + "@opentelemetry/semantic-conventions": "^1.29.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.3.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/sdk-trace-node": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-node/-/sdk-trace-node-2.5.1.tgz", + "integrity": "sha512-9lopQ6ZoElETOEN0csgmtEV5/9C7BMfA7VtF4Jape3i954b6sTY2k3Xw3CxUTKreDck/vpAuJM+EDo4zheUw+A==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/context-async-hooks": "2.5.1", + "@opentelemetry/core": "2.5.1", + "@opentelemetry/sdk-trace-base": "2.5.1" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": ">=1.0.0 <1.10.0" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.39.0.tgz", + "integrity": "sha512-R5R9tb2AXs2IRLNKLBJDynhkfmx7mX0vi8NkhZb3gUkPWHn6HXk5J8iQ/dql0U3ApfWym4kXXmBDRGO+oeOfjg==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.41.2", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.41.2.tgz", + "integrity": "sha512-4mhWm3Z8z+i508zQJ7r6Xi7y4mmoJpdvH0fZPFRkWrdp5fq7hhZ2HhYokEOLkfqSMgPR4Z9EyB3DBkbKGOqZiQ==", + "license": "Apache-2.0", + "dependencies": { + "@opentelemetry/core": "^2.0.0" + }, + "engines": { + "node": "^18.19.0 || >=20.6.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, "license": "MIT", "optional": true, "os": [ @@ -3357,6 +5880,70 @@ "@primer/behaviors": "^1.3.4" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, "node_modules/@rollup/rollup-android-arm-eabi": { "version": "4.59.0", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.59.0.tgz", @@ -3908,6 +6495,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/aws-lambda": { + "version": "8.10.161", + "resolved": "https://registry.npmjs.org/@types/aws-lambda/-/aws-lambda-8.10.161.tgz", + "integrity": "sha512-rUYdp+MQwSFocxIOcSsYSF3YYYC/uUpMbCY/mbO21vGqfrEYvNSoPyKYDj6RhXXpPfS0KstW9RwG3qXh9sL7FQ==", + "license": "MIT" + }, "node_modules/@types/body-parser": { "version": "1.19.5", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.5.tgz", @@ -3918,6 +6511,15 @@ "@types/node": "*" } }, + "node_modules/@types/bunyan": { + "version": "1.8.11", + "resolved": "https://registry.npmjs.org/@types/bunyan/-/bunyan-1.8.11.tgz", + "integrity": "sha512-758fRH7umIMk5qt5ELmRMff4mLDlN+xyYzC+dkPTdKwbSkJFvz6xwyScrytPU0QIBbRRwbiE8/BIg8bpajerNQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/caseless": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz", @@ -3951,7 +6553,6 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "dependencies": { "@types/node": "*" } @@ -4177,6 +6778,15 @@ "@types/unist": "*" } }, + "node_modules/@types/memcached": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/@types/memcached/-/memcached-2.2.10.tgz", + "integrity": "sha512-AM9smvZN55Gzs2wRrqeMHVP7KE8KWgCJO/XL5yCly2xF6EKa4YlbpK+cLSAH4NG/Ah64HrlegmGqW8kYws7Vxg==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -4192,6 +6802,15 @@ "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" }, + "node_modules/@types/mysql": { + "version": "2.15.27", + "resolved": "https://registry.npmjs.org/@types/mysql/-/mysql-2.15.27.tgz", + "integrity": "sha512-YfWiV16IY0OeBfBCk8+hXKmdTKrKlwKN1MNKAPBu5JYxLwBEZl7QzeEpGnlZb3VMGJrrGmB84gXiH+ofs/TezA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/node": { "version": "24.9.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-24.9.2.tgz", @@ -4201,6 +6820,35 @@ "undici-types": "~7.16.0" } }, + "node_modules/@types/oracledb": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/@types/oracledb/-/oracledb-6.5.2.tgz", + "integrity": "sha512-kK1eBS/Adeyis+3OlBDMeQQuasIDLUYXsi2T15ccNJ0iyUpQ4xDF7svFu3+bGVrI0CMBUclPciz+lsQR3JX3TQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/pg": { + "version": "8.15.6", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.15.6.tgz", + "integrity": "sha512-NoaMtzhxOrubeL/7UZuNTrejB4MPAJ0RpxZqXQf2qXuVlTPuG6Y8p4u9dKRaue4yjmC7ZhzVO2/Yyyn25znrPQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.7.tgz", + "integrity": "sha512-U4CwmGVQcbEuqpyju8/ptOKg6gEC+Tqsvj2xS9o1g71bUh8twxnC6ZL5rZKCsGN0iyH0CwgUyc9VR5owNQF9Ng==", + "license": "MIT", + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/prop-types": { "version": "15.7.4", "license": "MIT" @@ -4338,6 +6986,15 @@ "integrity": "sha512-0vQ4fz9TTM4bCdllYWEJ2JHBUXR9xqPtc70dJ7BMRDVfvZyYdrgey3nP5RRcVj+qAgnHJM8r9fvgrfnPMxdnhA==", "dev": true }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -5081,7 +7738,6 @@ "version": "8.15.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", - "dev": true, "license": "MIT", "peer": true, "bin": { @@ -5091,6 +7747,15 @@ "node": ">=0.4.0" } }, + "node_modules/acorn-import-attributes": { + "version": "1.9.5", + "resolved": "https://registry.npmjs.org/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz", + "integrity": "sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ==", + "license": "MIT", + "peerDependencies": { + "acorn": "^8" + } + }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", @@ -5512,6 +8177,15 @@ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-4.0.0.tgz", "integrity": "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ==" }, + "node_modules/bignumber.js": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.3.1.tgz", + "integrity": "sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==", + "license": "MIT", + "engines": { + "node": "*" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "dev": true, @@ -6061,6 +8735,12 @@ "node": ">=8" } }, + "node_modules/cjs-module-lexer": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", + "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", + "license": "MIT" + }, "node_modules/classnames": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", @@ -6171,6 +8851,49 @@ "resolved": "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz", "integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==" }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/clsx": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz", @@ -8729,6 +11452,12 @@ "node": ">= 0.6" } }, + "node_modules/forwarded-parse": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/forwarded-parse/-/forwarded-parse-2.1.2.tgz", + "integrity": "sha512-alTFZZQDKMporBH77856pXgzhEzaUVmLCDk+egLgIgHst3Tpndzz8MnKe+GzRJRfvVdn69HhpW7cmXzvtLvJAw==", + "license": "MIT" + }, "node_modules/fresh": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", @@ -8809,6 +11538,49 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/gaxios": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz", + "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==", + "license": "Apache-2.0", + "dependencies": { + "extend": "^3.0.2", + "https-proxy-agent": "^7.0.1", + "is-stream": "^2.0.0", + "node-fetch": "^2.6.9", + "uuid": "^9.0.1" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/gaxios/node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/gcp-metadata": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.1.tgz", + "integrity": "sha512-a4tiq7E0/5fTjxPAaH4jpjkSv/uCaU2p5KC6HVGrvl0cDjA8iBZv4vv1gyzlmK0ZUKqwpOyQMKzZQe3lTit77A==", + "license": "Apache-2.0", + "dependencies": { + "gaxios": "^6.1.1", + "google-logging-utils": "^0.0.2", + "json-bigint": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/gemoji": { "version": "4.2.1", "license": "MIT" @@ -8822,6 +11594,15 @@ "node": ">=6.9.0" } }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, "node_modules/get-east-asian-width": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", @@ -8989,6 +11770,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/google-logging-utils": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/google-logging-utils/-/google-logging-utils-0.0.2.tgz", + "integrity": "sha512-NEgUnEcBiP5HrPzufUkBzJOD/Sxsco3rLNo1F1TNf7ieU8ryUzBhqba8r756CjLX7rn3fHl6iLEwPYuqpoKgQQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=14" + } + }, "node_modules/gopd": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", @@ -9722,6 +12512,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-in-the-middle": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/import-in-the-middle/-/import-in-the-middle-2.0.6.tgz", + "integrity": "sha512-3vZV3jX0XRFW3EJDTwzWoZa+RH1b8eTTx6YOCjglrLyPuepwoBti1k3L2dKwdCUrnVEfc5CuRuGstaC/uQJJaw==", + "license": "Apache-2.0", + "dependencies": { + "acorn": "^8.15.0", + "acorn-import-attributes": "^1.9.5", + "cjs-module-lexer": "^2.2.0", + "module-details-from-path": "^1.0.4" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "license": "MIT", @@ -10208,7 +13010,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -10440,6 +13241,15 @@ "node": ">=6" } }, + "node_modules/json-bigint": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz", + "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==", + "license": "MIT", + "dependencies": { + "bignumber.js": "^9.0.0" + } + }, "node_modules/json-bignum": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/json-bignum/-/json-bignum-0.0.3.tgz", @@ -10881,6 +13691,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/long": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/long/-/long-5.3.2.tgz", + "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", + "license": "Apache-2.0" + }, "node_modules/longest-streak": { "version": "3.0.0", "license": "MIT", @@ -12127,6 +14943,12 @@ "dev": true, "license": "MIT" }, + "node_modules/module-details-from-path": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.4.tgz", + "integrity": "sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==", + "license": "MIT" + }, "node_modules/ms": { "version": "2.1.2", "license": "MIT" @@ -12678,6 +15500,26 @@ "license": "MIT", "optional": true }, + "node_modules/node-fetch": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", + "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -13367,6 +16209,37 @@ "through": "~2.3" } }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.13.0.tgz", + "integrity": "sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -13468,6 +16341,45 @@ "version": "4.1.0", "license": "MIT" }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz", + "integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "license": "MIT", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", @@ -13523,6 +16435,30 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/protobufjs": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.0.0.tgz", + "integrity": "sha512-jx6+sE9h/UryaCZhsJWbJtTEy47yXoGNYI4z8ZaRncM0zBKeRqjO2JEcOUYwrYGb1WLhXM1FfMzW3annvFv0rw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "license": "MIT", @@ -13969,6 +16905,15 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/require-from-string": { "version": "2.0.2", "license": "MIT", @@ -13976,6 +16921,19 @@ "node": ">=0.10.0" } }, + "node_modules/require-in-the-middle": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-8.0.1.tgz", + "integrity": "sha512-QT7FVMXfWOYFbeRBF6nu+I6tr2Tf3u0q8RIEjNob/heKY/nh7drD/k7eeMFmSQgnTtCzLDcCu/XEnpW2wk4xCQ==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.5", + "module-details-from-path": "^1.0.3" + }, + "engines": { + "node": ">=9.3.0 || >=8.10.0 <9.0.0" + } + }, "node_modules/requires-port": { "version": "1.0.0", "license": "MIT" @@ -15598,6 +18556,12 @@ "nodetouch": "bin/nodetouch.js" } }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "license": "MIT" + }, "node_modules/trim-lines": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", @@ -16702,6 +19666,12 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "license": "BSD-2-Clause" + }, "node_modules/website-scraper": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/website-scraper/-/website-scraper-5.3.1.tgz", @@ -16846,6 +19816,16 @@ "node": ">=18" } }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "license": "MIT", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "dev": true, @@ -17087,6 +20067,15 @@ "node": ">=0.4" } }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", @@ -17097,7 +20086,6 @@ "version": "2.8.2", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.2.tgz", "integrity": "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A==", - "dev": true, "license": "ISC", "bin": { "yaml": "bin.mjs" @@ -17109,6 +20097,33 @@ "url": "https://github.com/sponsors/eemeli" } }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "license": "ISC", + "engines": { + "node": ">=12" + } + }, "node_modules/yocto-queue": { "version": "0.1.0", "dev": true, diff --git a/package.json b/package.json index b6b5dacd681f..51fbb0747bcd 100644 --- a/package.json +++ b/package.json @@ -166,6 +166,11 @@ "@octokit/graphql": "9.0.1", "@octokit/plugin-retry": "8.0.1", "@octokit/request-error": "7.0.0", + "@opentelemetry/api": "^1.9.0", + "@opentelemetry/auto-instrumentations-node": "^0.69.0", + "@opentelemetry/core": "^2.5.1", + "@opentelemetry/exporter-trace-otlp-proto": "^0.212.0", + "@opentelemetry/sdk-node": "^0.212.0", "@primer/behaviors": "^1.10.2", "@primer/css": "^21.3.1", "@primer/live-region-element": "^0.7.2", diff --git a/src/app/404/page.tsx b/src/app/404/page.tsx deleted file mode 100644 index ea69f26de66f..000000000000 --- a/src/app/404/page.tsx +++ /dev/null @@ -1,20 +0,0 @@ -import { Client404Wrapper } from '@/app/components/Client404Wrapper' -import { createServerAppRouterContext } from '@/app/lib/server-context-utils' -import { headers } from 'next/headers' -import type { Metadata } from 'next' - -export const dynamic = 'force-dynamic' - -export const metadata: Metadata = { - title: '404 - Page not found', - other: { status: '404' }, -} - -export default async function Page404() { - const headersList = await headers() - const pathname = headersList.get('x-pathname') || '/404' - - const appContext = createServerAppRouterContext(pathname) - - return -} diff --git a/src/app/README.md b/src/app/README.md deleted file mode 100644 index 02da61ada4ef..000000000000 --- a/src/app/README.md +++ /dev/null @@ -1,71 +0,0 @@ -# App Router (`src/app`) - -This directory contains the [Next.js App Router](https://nextjs.org/docs/app) implementation for GitHub Docs. It currently serves as the application shell, handling the root layout, global providers, and 404 error pages, while coexisting with the Pages Router implementation. - -## Purpose & Scope - -The `src/app` directory is the entry point for the Next.js App Router. Its primary responsibilities are: -- Defining the root HTML structure and metadata. -- Initializing global client-side context providers (Theme, Locale, Languages). -- Handling global "Not Found" (404) scenarios. -- Providing a bridge between the modern App Router architecture and the `MainContext` used by existing components. - -We began this migration because we anticipate `@primer/react` will eventually drop support for the Pages Router. If that happens, we will be unable to upgrade `@primer/react`, effectively blocking us from receiving any future design system updates. Moving to the App Router prevents this and aligns us with the broader Next.js ecosystem. - -## Architecture & Key Assets - -### Directory Structure - -- `layout.tsx`: The server-side Root Layout. It sets up the `` and `` tags, loads global styles, and defines metadata/viewport settings. -- `client-layout.tsx`: A client component (`'use client'`) that wraps the application in necessary React Context providers. This allows server components to compose client-side logic for theming and state management. -- `not-found.tsx`: The UI for 404 errors within the App Router. -- `lib/`: Utilities for context adaptation and routing logic. - - `app-router-context.ts`: Generates context data based on the current request path. - - `main-context-adapter.ts`: Adapts App Router data structures to match the `MainContext` shape, ensuring backward compatibility for components. -- `components/`: Client-side components specific to the App Router shell (e.g., wrappers for 404 pages, context providers). - -### Key Concepts - -- **Context Adaptation**: Since much of the codebase relies on a monolithic `MainContext`, this directory implements adapters to construct a compatible context object from App Router primitives. This allows us to reuse existing components without rewriting them immediately. -- **Hybrid Routing**: The application currently operates in a hybrid mode. While `src/app` defines the outer shell, many specific routes and page rendering logic may still reside in the Pages Router (`src/pages`) or are being incrementally migrated. - -## Setup & Usage - -### Development - -Standard Next.js App Router conventions apply. To add a new route using the App Router, create a folder with a `page.tsx` file inside `src/app`. - -Useful documentation: -- [Next.js App Router Documentation](https://nextjs.org/docs/app) -- [Migrating from Pages to App Router](https://nextjs.org/docs/app/building-your-application/upgrading/app-router-migration) - -### Testing - -Tests for App Router logic should be placed alongside the components if applicable. - -Tests that verify Next.js behavior (like 404 handling) can be found in `src/frame/tests/next.ts`. - -## Data & External Dependencies - -- **Data Sources**: - - Consumes UI strings and language data from `src/data-directory` (via `getUIDataMerged`). - - Uses `src/languages` for locale definitions. -- **External Libraries**: - - `@primer/react`: Used for the design system and theming provider. - - `next`: The core framework. - -## Cross-links & Ownership - -- **Owner**: Docs Engineering -- **Related Directories**: - - `src/pages`: The Pages Router implementation. - - `src/frame`: Server and middleware logic that interacts with routing. - - `src/data-directory`: Source of static data used in layouts. - -## Current State & Next Steps - -- **Current State**: The App Router handles the root layout and 404s. It provides a compatibility layer for existing contexts. -- **Next Steps**: - - Migrate individual page routes from `src/pages` to `src/app`. - - Refactor components to reduce dependency on the monolithic `MainContext`. - - Improve data fetching patterns to use React Server Components (RSC) more effectively. \ No newline at end of file diff --git a/src/app/_not-found/page.tsx b/src/app/_not-found/page.tsx deleted file mode 100644 index 562bf64ed89e..000000000000 --- a/src/app/_not-found/page.tsx +++ /dev/null @@ -1,7 +0,0 @@ -import { notFound } from 'next/navigation' - -// This page handles internal /_not-found redirects from Express middleware -export default function InternalNotFound() { - // This will trigger Next.js to render the not-found.tsx page - notFound() -} diff --git a/src/app/client-layout.tsx b/src/app/client-layout.tsx deleted file mode 100644 index aa657c4b62e2..000000000000 --- a/src/app/client-layout.tsx +++ /dev/null @@ -1,122 +0,0 @@ -'use client' - -import React, { useEffect, useMemo, useState } from 'react' -import type { JSX } from 'react' -import { ThemeProvider } from '@primer/react' - -import { LocaleProvider } from '@/app/lib/locale-context' -import { useDetectLocale } from '@/app/lib/use-detect-locale' -import { useTheme } from '@/color-schemes/components/useTheme' -import { initializeEvents } from '@/events/components/events' -import { CTAPopoverProvider } from '@/frame/components/context/CTAContext' -import { SharedUIContextProvider } from '@/frame/components/context/SharedUIContext' -import { LanguagesContext, LanguagesContextT } from '@/languages/components/LanguagesContext' -import { languages, type LanguageCode } from '@/languages/lib/languages' -import { MainContextProvider } from '@/app/components/MainContextProvider' -import { createMinimalMainContext } from '@/app/lib/main-context-adapter' -import type { AppRouterContext } from '@/app/lib/app-router-context' - -interface ClientLayoutProps { - readonly children: React.ReactNode - readonly appContext?: AppRouterContext - readonly pageData?: { - title?: string - fullTitle?: string - introPlainText?: string - topics?: string[] - documentType?: string - type?: string - hidden?: boolean - } -} - -export function ClientLayout({ children, appContext, pageData }: ClientLayoutProps): JSX.Element { - const { theme } = useTheme() - const locale: LanguageCode = useDetectLocale() - const [isInitialized, setIsInitialized] = useState(false) - const [initializationError, setInitializationError] = useState(null) - - const languagesContext: LanguagesContextT = useMemo(() => ({ languages }), []) - - // Create MainContext-compatible data for App Router - const mainContext = useMemo( - () => createMinimalMainContext(pageData, appContext), - [pageData, appContext], - ) - - useEffect(() => { - const initializeTheme = async (): Promise => { - try { - const html = document.documentElement - - if (theme.css?.colorMode) { - html.setAttribute('data-color-mode', theme.css.colorMode) - } - - if (theme.css?.darkTheme) { - html.setAttribute('data-dark-theme', theme.css.darkTheme) - } - - if (theme.css?.lightTheme) { - html.setAttribute('data-light-theme', theme.css.lightTheme) - } - - if (!isInitialized) { - await initializeEvents() - setIsInitialized(true) - } - } catch (error) { - console.error('Failed to initialize theme:', error) - setInitializationError(error as Error) - } - } - - initializeTheme() - }, [theme, isInitialized]) - - if (initializationError) { - return ( -
-
-

Something went wrong

-

Please try refreshing the page.

- -
-
- ) - } - - return ( - - - - - - -
{children}
-
-
-
-
-
-
- ) -} diff --git a/src/app/components/AppRouterFooter.tsx b/src/app/components/AppRouterFooter.tsx deleted file mode 100644 index ac7e40922083..000000000000 --- a/src/app/components/AppRouterFooter.tsx +++ /dev/null @@ -1,83 +0,0 @@ -'use client' - -import { useAppRouterMainContext } from '@/app/components/AppRouterMainContext' -import { createTranslationFunctions } from '@/languages/lib/translation-utils' -import { LinkExternalIcon } from '@primer/octicons-react' - -export function AppRouterFooter() { - const context = useAppRouterMainContext() - - const { t } = createTranslationFunctions(context.site.data.ui, 'footer') - - return ( -
- {context.currentLanguage !== 'en' &&

{t('legal_heading')}

} - - {/* Machine translation notice for non-English languages */} - {context.currentLanguage !== 'en' &&

{t('machine')}

} - - -
- ) -} diff --git a/src/app/components/AppRouterHeader.tsx b/src/app/components/AppRouterHeader.tsx deleted file mode 100644 index 85c06fc3d467..000000000000 --- a/src/app/components/AppRouterHeader.tsx +++ /dev/null @@ -1,29 +0,0 @@ -'use client' - -import { MarkGithubIcon } from '@primer/octicons-react' -import { useAppRouterMainContext } from '@/app/components/AppRouterMainContext' -import { createTranslationFunctions } from '@/languages/lib/translation-utils' - -export function AppRouterHeader() { - const context = useAppRouterMainContext() - - const { t } = createTranslationFunctions(context.site.data.ui, 'header') - - const siteTitle = t('github_docs') - - return ( -
-
- -
-
- ) -} diff --git a/src/app/components/AppRouterLanguagesContext.tsx b/src/app/components/AppRouterLanguagesContext.tsx deleted file mode 100644 index e78a3e6c1e78..000000000000 --- a/src/app/components/AppRouterLanguagesContext.tsx +++ /dev/null @@ -1,54 +0,0 @@ -'use client' - -import React, { createContext, useContext } from 'react' -import { languages, type LanguageCode } from '@/languages/lib/languages' - -export type AppRouterLanguageItem = { - name: string - nativeName?: string - code: string - hreflang?: string -} - -export type AppRouterLanguagesContextT = { - languages: Record - currentLanguage?: LanguageCode -} - -export const AppRouterLanguagesContext = createContext(null) - -export const useAppRouterLanguages = (): AppRouterLanguagesContextT => { - const context = useContext(AppRouterLanguagesContext) - - if (!context) { - throw new Error( - '"useAppRouterLanguages" may only be used inside "AppRouterLanguagesContext.Provider"', - ) - } - - return context -} - -/** - * Provider component for App Router language context - */ -interface AppRouterLanguagesProviderProps { - children: React.ReactNode - currentLanguage?: LanguageCode -} - -export function AppRouterLanguagesProvider({ - children, - currentLanguage, -}: AppRouterLanguagesProviderProps) { - const value: AppRouterLanguagesContextT = { - languages, - currentLanguage, - } - - return ( - - {children} - - ) -} diff --git a/src/app/components/AppRouterMainContext.tsx b/src/app/components/AppRouterMainContext.tsx deleted file mode 100644 index 74b440ff2094..000000000000 --- a/src/app/components/AppRouterMainContext.tsx +++ /dev/null @@ -1,52 +0,0 @@ -'use client' -import type { AppRouterContext } from '@/app/lib/app-router-context' -import type { MainContextT } from '@/frame/components/context/MainContext' -import { adaptAppRouterContextToMainContext } from '@/app/lib/main-context-adapter' -import { createContext, ReactNode, useContext, useMemo } from 'react' - -export const AppRouterMainContext = createContext(null) - -// Provides MainContext-compatible data -export const AppRouterCompatMainContext = createContext(null) - -export function AppRouterMainContextProvider({ - children, - context, -}: { - children: ReactNode - context: AppRouterContext -}) { - // Create a MainContext-compatible version for existing components - const mainContextCompat = useMemo(() => adaptAppRouterContextToMainContext(context), [context]) - - return ( - - - {children} - - - ) -} - -export function useAppRouterMainContext(): AppRouterContext { - const context = useContext(AppRouterMainContext) - - if (!context) { - throw new Error('useAppRouterMainContext must be used within AppRouterMainContextProvider') - } - - return context -} - -// Hook for components that need MainContext compatibility -export function useAppRouterCompatMainContext(): MainContextT { - const context = useContext(AppRouterCompatMainContext) - - if (!context) { - throw new Error( - 'useAppRouterCompatMainContext must be used within AppRouterMainContextProvider', - ) - } - - return context -} diff --git a/src/app/components/Client404Wrapper.tsx b/src/app/components/Client404Wrapper.tsx deleted file mode 100644 index 22df8fcf9b60..000000000000 --- a/src/app/components/Client404Wrapper.tsx +++ /dev/null @@ -1,41 +0,0 @@ -'use client' - -import { AppRouterFooter } from '@/app/components/AppRouterFooter' -import { AppRouterHeader } from '@/app/components/AppRouterHeader' -import { AppRouterLanguagesProvider } from '@/app/components/AppRouterLanguagesContext' -import { AppRouterMainContextProvider } from '@/app/components/AppRouterMainContext' -import type { ServerAppRouterContext } from '@/app/lib/server-context-utils' -import { createTranslationFunctions } from '@/languages/lib/translation-utils' -import { CommentDiscussionIcon } from '@primer/octicons-react' - -interface Client404WrapperProps { - appContext: ServerAppRouterContext -} - -export function Client404Wrapper({ appContext }: Client404WrapperProps) { - const { t } = createTranslationFunctions(appContext.site.data.ui, 'not_found') - return ( - - -
- - {/* Main Content */} -
- -
- -
-
-
- ) -} diff --git a/src/app/components/ClientNotFoundWrapper.tsx b/src/app/components/ClientNotFoundWrapper.tsx deleted file mode 100644 index f66dda8224af..000000000000 --- a/src/app/components/ClientNotFoundWrapper.tsx +++ /dev/null @@ -1,20 +0,0 @@ -'use client' - -import { AppRouterMainContextProvider } from '@/app/components/AppRouterMainContext' -import { AppRouterLanguagesProvider } from '@/app/components/AppRouterLanguagesContext' -import { NotFoundContent } from '@/app/components/NotFoundContent' -import type { ServerAppRouterContext } from '@/app/lib/server-context-utils' - -interface ClientNotFoundWrapperProps { - appContext: ServerAppRouterContext -} - -export function ClientNotFoundWrapper({ appContext }: ClientNotFoundWrapperProps) { - return ( - - - - - - ) -} diff --git a/src/app/components/MainContextProvider.tsx b/src/app/components/MainContextProvider.tsx deleted file mode 100644 index 708e6e5889c4..000000000000 --- a/src/app/components/MainContextProvider.tsx +++ /dev/null @@ -1,17 +0,0 @@ -'use client' - -import type { ReactNode } from 'react' -import { MainContext, type MainContextT } from '@/frame/components/context/MainContext' - -interface MainContextProviderProps { - children: ReactNode - value: MainContextT -} - -/** - * App Router compatible MainContext provider - * This allows reusing existing components that depend on MainContext - */ -export function MainContextProvider({ children, value }: MainContextProviderProps) { - return {children} -} diff --git a/src/app/components/NotFoundContent.tsx b/src/app/components/NotFoundContent.tsx deleted file mode 100644 index 6a3de43559fc..000000000000 --- a/src/app/components/NotFoundContent.tsx +++ /dev/null @@ -1,33 +0,0 @@ -'use client' -import { AppRouterHeader } from '@/app/components/AppRouterHeader' -import { useAppRouterMainContext } from '@/app/components/AppRouterMainContext' -import { ServerFooter } from '@/app/components/ServerFooter' -import { createTranslationFunctions } from '@/languages/lib/translation-utils' -import { CommentDiscussionIcon } from '@primer/octicons-react' - -export function NotFoundContent() { - const context = useAppRouterMainContext() - const { t } = createTranslationFunctions(context.site.data.ui, 'not_found') - - return ( -
- - -
- -
- - -
- ) -} diff --git a/src/app/components/ServerFooter.tsx b/src/app/components/ServerFooter.tsx deleted file mode 100644 index a6d5913a4bf6..000000000000 --- a/src/app/components/ServerFooter.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import { getUIDataMerged } from '@/data-directory/lib/get-data' -import { createTranslationFunctions } from '@/languages/lib/translation-utils' -import { LinkExternalIcon } from '@primer/octicons-react' -import type { LanguageCode } from '@/languages/lib/languages' - -interface ServerFooterProps { - currentLanguage: LanguageCode -} - -export function ServerFooter({ currentLanguage }: ServerFooterProps) { - // Load translations on server-side - this ensures all footer translations work - const uiData = getUIDataMerged(currentLanguage) - const { t } = createTranslationFunctions(uiData, 'footer') - - return ( -
-

{t('legal_heading')}

- - {/* Machine translation notice for non-English languages */} - {currentLanguage !== 'en' &&

{t('machine')}

} - - -
- ) -} diff --git a/src/app/components/hooks/useAppRouterVersion.ts b/src/app/components/hooks/useAppRouterVersion.ts deleted file mode 100644 index ef032e8d6d62..000000000000 --- a/src/app/components/hooks/useAppRouterVersion.ts +++ /dev/null @@ -1,12 +0,0 @@ -'use client' - -import { usePathname } from 'next/navigation' -import { getVersionInfoFromPath } from '@/app/lib/version-utils' - -/** - * App Router compatible version hook - */ -export function useAppRouterVersion() { - const pathname = usePathname() - return getVersionInfoFromPath(pathname ?? '') -} diff --git a/src/app/layout.tsx b/src/app/layout.tsx index a14c6bd1aaa6..9d823c65d72a 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,55 +1,8 @@ -import '@/frame/stylesheets/index.scss' -import type { Metadata, Viewport } from 'next' -import { ReactNode } from 'react' -import type { JSX } from 'react' +// Stub layout kept so Next.js enables App Router mode, which relaxes +// the "global CSS only in _app" restriction needed by transpilePackages. +// All routing is handled by the Pages Router (src/pages/). +import type { ReactNode } from 'react' -export const metadata: Metadata = { - title: { - template: '%s | GitHub Docs', - default: 'GitHub Docs', - }, - icons: { - icon: [ - { url: '/assets/cb-345/images/site/favicon.png', sizes: '32x32', type: 'image/png' }, - { url: '/assets/cb-345/images/site/favicon.ico', sizes: '48x48', type: 'image/x-icon' }, - ], - shortcut: '/assets/cb-345/images/site/favicon.ico', - apple: '/assets/cb-345/images/site/favicon.png', - }, - verification: { - google: [ - 'OgdQc0GZfjDI52wDv1bkMT-SLpBUo_h5nn9mI9L22xQ', - 'c1kuD-K2HIVF635lypcsWPoD4kilo5-jA_wBFyT4uMY', - ], - }, -} - -export const viewport: Viewport = { - width: 'device-width', - initialScale: 1, -} - -interface RootLayoutProps { - readonly children: ReactNode -} - -// Root layout for App Router pages -export default function RootLayout({ children }: RootLayoutProps): JSX.Element { - return ( - - - - {/* DNS prefetch for performance */} - - - - {children} - - ) +export default function RootLayout({ children }: { children: ReactNode }) { + return children } diff --git a/src/app/lib/app-router-context.ts b/src/app/lib/app-router-context.ts deleted file mode 100644 index 455705576dec..000000000000 --- a/src/app/lib/app-router-context.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { getUIDataMerged } from '@/data-directory/lib/get-data' -import { type LanguageCode } from '@/languages/lib/languages' -import { translate } from '@/languages/lib/translation-utils' -import { extractLanguageFromPath } from '@/app/lib/language-utils' -import { type UIStrings } from '@/frame/components/context/MainContext' - -export interface AppRouterContext { - currentLanguage: LanguageCode - currentVersion: string - sitename: string - site: { - data: { - ui: UIStrings - } - } -} - -/** - * Create App Router context from pathname - */ -export function createAppRouterContext( - pathname: string = '/', - fallbackLanguage?: LanguageCode, -): AppRouterContext { - let language = extractLanguageFromPath(pathname) - - // Use fallback if provided and URL doesn't specify language - if (language === 'en' && fallbackLanguage && fallbackLanguage !== 'en') { - language = fallbackLanguage - } - - const version = 'free-pro-team@latest' - - // Load UI data directly from data directory - const uiData = getUIDataMerged(language) - const siteName = translate(uiData, 'header.github_docs', 'GitHub Docs') - - return { - currentLanguage: language, - currentVersion: version, - sitename: siteName, - site: { - data: { - ui: uiData, - }, - }, - } -} diff --git a/src/app/lib/constants.ts b/src/app/lib/constants.ts deleted file mode 100644 index 0864885120f1..000000000000 --- a/src/app/lib/constants.ts +++ /dev/null @@ -1,18 +0,0 @@ -/** - * App Router compatible constants - * These can be safely imported by both server and client components - */ - -export const DEFAULT_VERSION = 'free-pro-team@latest' - -// Version utility functions that don't use router hooks -export function getVersionInfo(currentVersion: string = DEFAULT_VERSION) { - return { - currentVersion, - isEnterprise: currentVersion.includes('enterprise'), - isEnterpriseCloud: currentVersion.includes('cloud'), - isEnterpriseServer: currentVersion.includes('enterprise-server'), - } -} - -export type VersionInfo = ReturnType diff --git a/src/app/lib/language-utils.ts b/src/app/lib/language-utils.ts deleted file mode 100644 index c3c88dea6212..000000000000 --- a/src/app/lib/language-utils.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { languageKeys, type LanguageCode } from '@/languages/lib/languages' - -/** - * Extract language from URL path - * Handles paths like /en/something, /es/articles, etc. - */ -export function extractLanguageFromPath(path: string): LanguageCode { - try { - const pathSegments = path.split('/') - const firstSegment = pathSegments[1] - - if (firstSegment && languageKeys.includes(firstSegment)) { - return firstSegment as LanguageCode - } - } catch (error) { - console.warn('Failed to extract language from path:', error) - } - return 'en' -} - -/** - * Check if a path contains a language prefix - */ -export function hasLanguagePrefix(path: string): boolean { - const pathSegments = path.split('/') - const firstSegment = pathSegments[1] - return Boolean(firstSegment && languageKeys.includes(firstSegment)) -} - -/** - * Remove language prefix from path - * e.g., /es/articles/example -> /articles/example - */ -export function stripLanguagePrefix(path: string): string { - if (hasLanguagePrefix(path)) { - const pathSegments = path.split('/') - return `/${pathSegments.slice(2).join('/')}` - } - return path -} - -/** - * Add language prefix to path if it doesn't have one - * e.g., /articles/example + 'es' -> /es/articles/example - */ -export function addLanguagePrefix(path: string, language: LanguageCode): string { - if (hasLanguagePrefix(path)) { - return path - } - return `/${language}${path === '/' ? '' : path}` -} diff --git a/src/app/lib/locale-context.tsx b/src/app/lib/locale-context.tsx deleted file mode 100644 index e06327f3c644..000000000000 --- a/src/app/lib/locale-context.tsx +++ /dev/null @@ -1,118 +0,0 @@ -'use client' - -import { createContext, useContext, ReactNode, useMemo } from 'react' -import type { JSX } from 'react' -import { languages, languageKeys, type LanguageCode } from '@/languages/lib/languages' - -interface LocaleContextType { - readonly locale: LanguageCode - readonly isValidLocale: (locale: string) => locale is LanguageCode - readonly getSupportedLocales: () => readonly LanguageCode[] - readonly getLocaleDisplayName: (locale: LanguageCode) => string - readonly getLocaleNativeName: (locale: LanguageCode) => string -} - -const LocaleContext = createContext(null) - -interface LocaleProviderProps { - readonly children: ReactNode - readonly locale: LanguageCode -} - -// Use client languages as the source of truth for supported locales -const SUPPORTED_LOCALES: readonly LanguageCode[] = languageKeys as LanguageCode[] - -/** - * Validates if a string is a supported locale - */ -function isValidLocale(locale: string): locale is LanguageCode { - return languageKeys.includes(locale) -} - -/** - * Gets display name for a locale from languages module - */ -function getLocaleDisplayName(locale: LanguageCode): string { - return languages[locale]?.name || locale -} - -/** - * Gets native name for a locale from languages module - */ -function getLocaleNativeName(locale: LanguageCode): string { - return languages[locale]?.nativeName || languages[locale]?.name || locale -} - -/** - * Gets browser language preference as a valid locale - */ -function getBrowserLocale(): LanguageCode { - if (typeof window === 'undefined') return 'en' - - const browserLang = window.navigator.language.split('-')[0] - return isValidLocale(browserLang) ? browserLang : 'en' -} - -/** - * Enhanced locale provider with validation and error handling - */ -export function LocaleProvider({ children, locale }: LocaleProviderProps): JSX.Element { - const contextValue = useMemo( - () => ({ - locale: isValidLocale(locale) ? locale : 'en', - isValidLocale, - getSupportedLocales: () => SUPPORTED_LOCALES, - getLocaleDisplayName, - getLocaleNativeName, - }), - [locale], - ) - - return {children} -} - -/** - * Hook to get current locale with enhanced error handling - */ -export function useLocale(): LanguageCode { - const context = useContext(LocaleContext) - - if (context) { - return context.locale - } - - // Fallback for when not within LocaleProvider - // This handles cases where the hook is used outside of the provider - console.warn('useLocale called outside of LocaleProvider, using fallback') - return getBrowserLocale() -} - -/** - * Hook to validate locales - */ -export function useLocaleValidation() { - const context = useContext(LocaleContext) - - return { - isValidLocale: context?.isValidLocale ?? isValidLocale, - getSupportedLocales: context?.getSupportedLocales ?? (() => SUPPORTED_LOCALES), - getLocaleDisplayName: context?.getLocaleDisplayName ?? getLocaleDisplayName, - getLocaleNativeName: context?.getLocaleNativeName ?? getLocaleNativeName, - } -} - -/** - * Hook to get locale context (for advanced use cases) - */ -export function useLocaleContext(): LocaleContextType { - const context = useContext(LocaleContext) - - if (!context) { - throw new Error('useLocaleContext must be used within a LocaleProvider') - } - - return context -} - -export { isValidLocale, getLocaleDisplayName, getLocaleNativeName } -export type { LocaleContextType, LanguageCode } diff --git a/src/app/lib/main-context-adapter.ts b/src/app/lib/main-context-adapter.ts deleted file mode 100644 index 666d968b49bd..000000000000 --- a/src/app/lib/main-context-adapter.ts +++ /dev/null @@ -1,105 +0,0 @@ -import type { MainContextT } from '@/frame/components/context/MainContext' -import type { AppRouterContext } from '@/app/lib/app-router-context' - -/** - * Adapter to create MainContext-compatible data from App Router context - * Allows reusing existing components that depend on MainContext - */ -export function adaptAppRouterContextToMainContext( - appContext: AppRouterContext, - overrides: Partial = {}, -): MainContextT { - const baseContext: MainContextT = { - data: { - ui: appContext.site.data.ui, - reusables: {}, - variables: { - release_candidate: { version: null }, - }, - }, - - // Default/fallback values that can be overridden - allVersions: {}, - breadcrumbs: { - product: { - title: '', - href: undefined, - }, - }, - communityRedirect: { - name: '', - href: '', - }, - currentPathWithoutLanguage: '', - currentProduct: undefined, - currentProductName: '', - currentProductTree: null, - currentVersion: appContext.currentVersion, - enterpriseServerReleases: { - isOldestReleaseDeprecated: false, - oldestSupported: '', - nextDeprecationDate: '', - supported: [], - releasesWithOldestDeprecationDate: [], - }, - enterpriseServerVersions: [], - error: '', - featureFlags: {}, - fullUrl: '', - isHomepageVersion: false, - nonEnterpriseDefaultVersion: 'free-pro-team@latest', - page: null, - relativePath: undefined, - sidebarTree: null, - status: 200, - xHost: '', - - // Apply any overrides - ...overrides, - } - - return baseContext -} - -/** - * For components that need MainContext data in App Router, - * this helper provides a minimal compatible context - */ -export function createMinimalMainContext( - pageData?: { - title?: string - fullTitle?: string - introPlainText?: string - documentType?: string - hidden?: boolean - }, - appContext?: AppRouterContext, -): MainContextT { - const defaultAppContext: AppRouterContext = appContext || { - currentLanguage: 'en', - currentVersion: 'free-pro-team@latest', - sitename: 'GitHub Docs', - site: { - data: { - ui: { - header: { github_docs: 'GitHub Docs' }, - footer: {}, - }, - }, - }, - } - - return adaptAppRouterContextToMainContext(defaultAppContext, { - page: pageData - ? { - documentType: pageData.documentType || 'article', - title: pageData.title || 'Page Not Found', - fullTitle: pageData.fullTitle || pageData.title, - introPlainText: pageData.introPlainText, - hidden: pageData.hidden || false, - noEarlyAccessBanner: false, - applicableVersions: [], - } - : null, - }) -} diff --git a/src/app/lib/routing-patterns.ts b/src/app/lib/routing-patterns.ts deleted file mode 100644 index b006abf66243..000000000000 --- a/src/app/lib/routing-patterns.ts +++ /dev/null @@ -1,118 +0,0 @@ -/** - * Shared routing patterns for determining App Router vs Pages Router routing decisions. - * This module centralizes pattern definitions to ensure consistency between - * app-router-gateway.ts and render-page.ts - */ - -// Define which routes should use App Router (without locale prefix) -const APP_ROUTER_ROUTES = new Set([ - '/_not-found', - '/404', - // Add more routes as you migrate them -]) - -/** - * Determines if a given path should be handled by the App Router - * @param path - The request path to check - * @param pageFound - Whether a page was found by the findPage middleware - * @returns true if the path should use App Router, false for Pages Router - */ -export function shouldUseAppRouter(path: string, pageFound: boolean = true): boolean { - // Strip locale prefix before checking - const strippedPath = stripLocalePrefix(path) - - // Check exact matches on the stripped path for specific App Router routes - if (APP_ROUTER_ROUTES.has(strippedPath)) { - return true - } - - // Special case: paths ending with /empty-categories should always 404 via App Router - // This handles translation tests where certain versioned paths should not exist - if (strippedPath.endsWith('/empty-categories')) { - return true - } - - // For 404 migration: If no page was found, use App Router for 404 handling - if (!pageFound) { - return true - } - - return false -} - -/** - * Checks if a path looks like a "junk path" that should be handled by shielding middleware - * These are paths like WordPress attacks, config files, etc. that need specific 404 handling - */ -export function isJunkPath(path: string): boolean { - // Common attack patterns and junk paths that should be handled by shielding - const junkPatterns = [ - /^\/wp-/, // WordPress paths: /wp-content, /wp-login.php, etc. - /^\/[^/]*\.php$/, // PHP files in root: xmlrpc.php, wp-login.php (but not /en/delicious-snacks/donuts.php) - /^\/~\w+/, // User directory paths: /~root, /~admin, etc. - /\/\.env/, // Environment files: /.env, /.env.local, etc. - /\/package(-lock)?\.json$/, // Node.js package files - /^\/_{2,}/, // Multiple underscores: ///, /\\, etc. - /^\/\\+/, // Backslash attacks - ] - - return junkPatterns.some((pattern) => pattern.test(path)) -} - -/** - * Checks if a path contains a version identifier (e.g., enterprise-server@3.16, enterprise-cloud@latest) - * This helps distinguish versioned docs paths from regular paths that should potentially use App Router - */ -export function isVersionedPath(path: string): boolean { - const strippedPath = stripLocalePrefix(path) - - // Check for version patterns: plan@release - // Examples: enterprise-server@3.16, enterprise-server@latest, enterprise-cloud@latest, free-pro-team@latest - const versionPattern = - /(enterprise-server@[\d.]+|enterprise-server@latest|enterprise-cloud@latest|free-pro-team@latest)/ - return versionPattern.test(strippedPath) -} - -/** - * Checks if a versioned path contains invalid segments that should result in 404 - * These should be routed to App Router for proper 404 handling - */ -export function isInvalidVersionedPath(path: string): boolean { - const strippedPath = stripLocalePrefix(path) - - // Check for obviously invalid paths that should 404 - // Example: /enterprise-server@latest/ANY/admin or /enterprise-server@12345/anything - return ( - strippedPath.includes('/ANY/') || - /enterprise-server@12345/.test(strippedPath) || - // Add other invalid patterns as needed - false - ) -} - -/** - * Decodes a URL path, handling URL-encoded characters like %40 -> @ - */ -export function decodePathSafely(path: string): string { - try { - return decodeURIComponent(path) - } catch { - // If decoding fails, use original path - return path - } -} - -/** - * Strips the locale prefix from the path if present - * e.g., /en/search -> /search - * e.g., /en/enterprise-server@3.17 -> /enterprise-server@3.17 - */ -export function stripLocalePrefix(path: string): string { - const decodedPath = decodePathSafely(path) - - const localeMatch = decodedPath.match(/^\/([a-z]{2})(\/.*)?$/) - if (localeMatch) { - return localeMatch[2] || '/' - } - return decodedPath -} diff --git a/src/app/lib/server-context-utils.ts b/src/app/lib/server-context-utils.ts deleted file mode 100644 index 3d4dcec2df13..000000000000 --- a/src/app/lib/server-context-utils.ts +++ /dev/null @@ -1,46 +0,0 @@ -import { extractLanguageFromPath } from '@/app/lib/language-utils' -import { extractVersionFromPath } from '@/app/lib/version-utils' -import { getUIDataMerged } from '@/data-directory/lib/get-data' -import { type LanguageCode } from '@/languages/lib/languages' -import { createTranslationFunctions, translate } from '@/languages/lib/translation-utils' -import type { UIStrings } from '@/frame/components/context/MainContext' - -export interface ServerAppRouterContext { - currentLanguage: LanguageCode - currentVersion: string - sitename: string - site: { data: { ui: UIStrings } } -} - -/** - * Server-side context creation using filesystem data - * Use in server components where filesystem access is available - */ -export function createServerAppRouterContext(pathname: string): ServerAppRouterContext { - const language = extractLanguageFromPath(pathname) - const currentVersion = extractVersionFromPath(pathname) - - const uiData = getUIDataMerged(language) - const siteName = translate(uiData, 'header.github_docs', 'GitHub Docs') - - return { - currentLanguage: language, - currentVersion, - sitename: siteName, - site: { data: { ui: uiData } }, - } -} - -/** - * Create server-side footer with translations - */ -export function createServerFooterContent(language: LanguageCode) { - const uiData = getUIDataMerged(language) - const { t } = createTranslationFunctions(uiData, 'footer') - - return { - t, - language, - footerData: uiData.footer || {}, - } -} diff --git a/src/app/lib/use-detect-locale.tsx b/src/app/lib/use-detect-locale.tsx deleted file mode 100644 index c367b9ef5131..000000000000 --- a/src/app/lib/use-detect-locale.tsx +++ /dev/null @@ -1,89 +0,0 @@ -'use client' - -import { usePathname } from 'next/navigation' -import { useMemo, useEffect, useState } from 'react' -import { languageKeys, type LanguageCode } from '@/languages/lib/languages' -import Cookies from '@/frame/components/lib/cookies' -import { USER_LANGUAGE_COOKIE_NAME } from '@/frame/lib/constants' - -/** - * Validates if a string is a supported locale using client languages - */ -function isValidLocale(locale: string): locale is LanguageCode { - return languageKeys.includes(locale) -} - -/** - * Hook to detect locale from various sources with fallback logic - */ -export function useDetectLocale(): LanguageCode { - const pathname = usePathname() - const [cookieLanguage, setCookieLanguage] = useState(null) - const [browserLanguage, setBrowserLanguage] = useState(null) - - // Read cookie and browser language on client-side mount - useEffect(() => { - const userLanguageCookie = Cookies.get(USER_LANGUAGE_COOKIE_NAME) - if (userLanguageCookie && isValidLocale(userLanguageCookie)) { - setCookieLanguage(userLanguageCookie) - } - - // Get language from browser as fallback - if (navigator?.language) { - const browserLocale = navigator.language.split('-')[0] - if (isValidLocale(browserLocale)) { - setBrowserLanguage(browserLocale) - } - } - }, []) - - return useMemo(() => { - // Priority order: - // 1. URL path - // 2. User language cookie - // 3. Browser language - // 4. Default to English - - // Extract locale from pathname (e.g., /es/search -> 'es') - if (pathname) { - const pathSegments = pathname.split('/') - const firstSegment = pathSegments[1] - - if (firstSegment && isValidLocale(firstSegment)) { - return firstSegment - } - } - - // Use cookie language if available - if (cookieLanguage) { - return cookieLanguage - } - - // Use browser language if available - if (browserLanguage) { - return browserLanguage - } - - return 'en' - }, [pathname, cookieLanguage, browserLanguage]) -} - -/** - * Utility function to detect locale from pathname (for server-side use) - */ -export function detectLocaleFromPath(pathname: string): LanguageCode { - const pathSegments = pathname.split('/') - const firstSegment = pathSegments[1] - - if (firstSegment && isValidLocale(firstSegment)) { - return firstSegment - } - - return 'en' -} - -export function getSupportedLocales(): readonly LanguageCode[] { - return languageKeys as LanguageCode[] -} - -export { isValidLocale } diff --git a/src/app/lib/version-utils.ts b/src/app/lib/version-utils.ts deleted file mode 100644 index 24f85ba75ecf..000000000000 --- a/src/app/lib/version-utils.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { DEFAULT_VERSION, getVersionInfo } from '@/app/lib/constants' - -/** - * Extract version from pathname (works in both server and client) - */ -export function extractVersionFromPath(pathname: string): string { - const pathSegments = pathname.split('/').filter(Boolean) - - const versionSegment = pathSegments.find( - (segment) => - segment.includes('enterprise-server') || - segment.includes('enterprise-cloud') || - segment === 'enterprise' || - segment === 'free-pro-team@latest', - ) - - return versionSegment || DEFAULT_VERSION -} - -/** - * Get version info from pathname (works in both server and client) - */ -export function getVersionInfoFromPath(pathname: string) { - const currentVersion = extractVersionFromPath(pathname) - return getVersionInfo(currentVersion) -} diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx deleted file mode 100644 index 4457ccaadeef..000000000000 --- a/src/app/not-found.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { ClientNotFoundWrapper } from '@/app/components/ClientNotFoundWrapper' -import { createServerAppRouterContext } from '@/app/lib/server-context-utils' -import { headers } from 'next/headers' -import type { Metadata } from 'next' - -export const dynamic = 'force-dynamic' - -export const metadata: Metadata = { - title: '404 - Page not found', - other: { status: '404' }, -} - -export default async function NotFoundPage() { - const headersList = await headers() - const pathname = headersList.get('x-pathname') || '/' - - // Create server context using utility function - const appContext = createServerAppRouterContext(pathname) - - return -} diff --git a/src/app/types.ts b/src/app/types.ts deleted file mode 100644 index 8b7be385f009..000000000000 --- a/src/app/types.ts +++ /dev/null @@ -1,84 +0,0 @@ -/** - * Enhanced type definitions for the app router with strict validation - */ - -import React from 'react' -import type { LanguageCode } from '@/languages/lib/languages' - -// Core theme types with strict validation -export type Theme = 'light' | 'dark' | 'auto' -export type ColorMode = 'light' | 'dark' - -// Re-export locale type from languages.ts for consistency -export type Locale = LanguageCode - -// Version and product identifiers with validation -export type VersionId = string -export type ProductId = string -export type CategoryId = string - -// Enhanced page parameters with validation -export interface PageParams { - readonly versionId?: VersionId - readonly productId?: ProductId - readonly categoryId?: CategoryId -} - -// Search parameters with better typing -export interface SearchParams { - readonly [key: string]: string | string[] | undefined -} - -// Route context with comprehensive typing -export interface RouteContext { - readonly locale: Locale - readonly versionId?: VersionId - readonly productId?: ProductId - readonly categoryId?: CategoryId -} - -// Theme configuration with complete typing -export interface ThemeConfig { - readonly theme: Theme - readonly colorMode: ColorMode - readonly component: { - readonly colorMode: ColorMode - readonly dayScheme: string - readonly nightScheme: string - } -} - -// Error types for better error handling -export interface AppError { - readonly message: string - readonly code: string - readonly statusCode: number - readonly context?: Record -} - -// Navigation item with accessibility support -export interface NavigationItem { - readonly href: string - readonly title: string - readonly isActive?: boolean - readonly ariaLabel?: string - readonly children?: readonly NavigationItem[] -} - -// Layout props with enhanced typing -export interface LayoutProps { - readonly children: React.ReactNode - readonly className?: string -} - -// Component props with better composition -export interface ComponentProps { - readonly className?: string - readonly children?: React.ReactNode - readonly 'data-testid'?: string -} - -// Utility types for better type safety -export type NonEmptyArray = [T, ...T[]] -export type RequiredFields = T & Required> -export type OptionalFields = Omit & Partial> diff --git a/src/app/validators.ts b/src/app/validators.ts deleted file mode 100644 index eaf42c0031ca..000000000000 --- a/src/app/validators.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { isValidLocale } from '@/app/lib/use-detect-locale' -import { PageParams, SearchParams, Theme } from './types' - -// Runtime validation helpers (theme-specific only, locale validation moved to use-detect-locale) -export const isValidTheme = (theme: string): theme is Theme => - ['light', 'dark', 'auto'].includes(theme) - -// Type guards for runtime validation -export const isPageParams = (obj: unknown): obj is PageParams => - typeof obj === 'object' && obj !== null - -export const isSearchParams = (obj: unknown): obj is SearchParams => - typeof obj === 'object' && obj !== null - -// Re-export locale validation -export { isValidLocale } diff --git a/src/article-api/lib/get-all-toc-items.ts b/src/article-api/lib/get-all-toc-items.ts index 8d616cf868e3..ae32ee52432c 100644 --- a/src/article-api/lib/get-all-toc-items.ts +++ b/src/article-api/lib/get-all-toc-items.ts @@ -1,5 +1,6 @@ import type { Context, Page } from '@/types' import type { LinkData } from '@/article-api/transformers/types' +import { renderLiquid } from '@/content-render/liquid/index' import { resolvePath } from './resolve-path' interface PageWithChildren extends Page { @@ -28,9 +29,16 @@ export async function getAllTocItems( options: { recurse?: boolean renderIntros?: boolean + /** Use Liquid-only rendering for titles and intros instead of the full + * Markdown/unified pipeline. Resolves {% data %} variables without + * the cost of Markdown parsing, unified processing, and Cheerio unwrap. */ + liquidOnly?: boolean + /** Only recurse into children whose resolved path starts with this prefix. + * Prevents cross-product traversal (e.g. /en/rest listing /enterprise-admin). */ + basePath?: string } = {}, ): Promise { - const { recurse = true, renderIntros = true } = options + const { recurse = true, renderIntros = true, liquidOnly = false } = options const pageWithChildren = page as PageWithChildren const languageCode = page.languageCode || 'en' @@ -44,43 +52,69 @@ export async function getAllTocItems( ) const pathname = pagePermalink ? pagePermalink.href : `/${languageCode}` - const items: TocItem[] = [] - - for (const childHref of pageWithChildren.children) { - const childPage = resolvePath(childHref, languageCode, pathname, context) as - | PageWithChildren - | undefined - - if (!childPage) continue - - const title = await childPage.renderTitle(context, { unwrap: true }) - const intro = - renderIntros && childPage.intro - ? await childPage.renderProp('intro', context, { textOnly: true }) - : '' - - const childPermalink = childPage.permalinks.find( - (p) => p.languageCode === languageCode && p.pageVersion === context.currentVersion, + // On the first call, set basePath to this page's path so recursion + // stays within the same product section. + const basePath = options.basePath ?? pathname + + const resolvedChildren = pageWithChildren.children + .map((childHref) => ({ + childHref, + childPage: resolvePath(childHref, languageCode, pathname, context) as + | PageWithChildren + | undefined, + })) + .filter( + (entry): entry is { childHref: string; childPage: PageWithChildren } => + entry.childPage !== undefined, ) - const href = childPermalink ? childPermalink.href : childHref - const category = childPage.category || [] + const items = await Promise.all( + resolvedChildren.map(async ({ childHref, childPage }) => { + const childPermalink = childPage.permalinks.find( + (p) => p.languageCode === languageCode && p.pageVersion === context.currentVersion, + ) + const href = childPermalink ? childPermalink.href : childHref + + let title: string + if (liquidOnly) { + const raw = childPage.shortTitle || childPage.title + try { + title = await renderLiquid(raw, context) + } catch { + // Fall back to raw frontmatter string if Liquid rendering fails + // (e.g. translation errors in non-English pages) + title = raw + } + } else { + title = await childPage.renderTitle(context, { unwrap: true }) + } - const item: TocItem = { - href, - title, - intro, - category, - childTocItems: [], - } + let intro = '' + if (renderIntros && childPage.intro) { + if (liquidOnly) { + const rawIntro = childPage.rawIntro || childPage.intro + try { + intro = await renderLiquid(rawIntro, context) + } catch { + intro = rawIntro + } + } else { + intro = await childPage.renderProp('intro', context, { textOnly: true }) + } + } - // Recursively get children if enabled - if (recurse && childPage.children && childPage.children.length > 0) { - item.childTocItems = await getAllTocItems(childPage, context, options) - } + const category = childPage.category || [] - items.push(item) - } + // Only recurse if the child is within the same product section + const withinSection = href.startsWith(basePath) + const childTocItems = + recurse && withinSection && childPage.children && childPage.children.length > 0 + ? await getAllTocItems(childPage, context, { ...options, basePath }) + : [] + + return { href, title, intro, category, childTocItems } as TocItem + }), + ) return items } diff --git a/src/article-api/tests/discovery-landing-transformer.ts b/src/article-api/tests/discovery-landing-transformer.ts index a48bd6e10667..fe013bf7f5e6 100644 --- a/src/article-api/tests/discovery-landing-transformer.ts +++ b/src/article-api/tests/discovery-landing-transformer.ts @@ -51,4 +51,39 @@ describe('discovery landing transformer', () => { // Should have at least one section expect(res.body).toContain('##') }) + + test('articles include intros rendered with Liquid', async () => { + const res = await get(makeURL('/en/get-started/article-grid-discovery')) + expect(res.statusCode).toBe(200) + + // Articles should have intros (Liquid-rendered from frontmatter) + expect(res.body).toContain('This is the first test article for the article grid component.') + expect(res.body).toContain('This is the fourth test article for the article grid component.') + }) + + test('filters articles by includedCategories', async () => { + const res = await get(makeURL('/en/get-started/discovery-filtered')) + expect(res.statusCode).toBe(200) + + // "Included Article" has category "Getting started" and should appear + expect(res.body).toContain('[Included Article]') + + // "Excluded Article" has category "Advanced" and should be filtered out + expect(res.body).not.toContain('[Excluded Article]') + }) + + test('recursive articles stay within product section (basePath guard)', async () => { + const res = await get(makeURL('/en/get-started/article-grid-discovery')) + expect(res.statusCode).toBe(200) + + // All four articles from both categories should appear + expect(res.body).toContain('[Grid Article One]') + expect(res.body).toContain('[Grid Article Two]') + expect(res.body).toContain('[Grid Article Three]') + expect(res.body).toContain('[Grid Article Four]') + + // Category pages themselves should NOT appear (excludeParents: true) + expect(res.body).not.toContain('[Grid Category One]') + expect(res.body).not.toContain('[Grid Category Two]') + }) }) diff --git a/src/article-api/transformers/discovery-landing-transformer.ts b/src/article-api/transformers/discovery-landing-transformer.ts index 87b864c2a83b..9f7e2e804022 100644 --- a/src/article-api/transformers/discovery-landing-transformer.ts +++ b/src/article-api/transformers/discovery-landing-transformer.ts @@ -129,12 +129,17 @@ export class DiscoveryLandingTransformer implements PageTransformer { } } - // Articles section: recursively gather ALL descendant articles - // This matches the behavior of the site which uses genericTocFlat/genericTocNested + // Articles section: recursively gather descendant articles within + // this product section. Uses Liquid-only rendering for titles and intros + // instead of the full Markdown/unified pipeline, which would take 30s+ + // for large sections like /rest (297 descendants × 2 renderContent calls). + // The basePath guard prevents cross-product recursion (e.g. /rest listing + // /enterprise-admin children that point outside the /rest hierarchy). if (discoveryPage.children && discoveryPage.children.length > 0) { const tocItems = await getAllTocItems(page, context, { recurse: true, renderIntros: true, + liquidOnly: true, }) // Flatten to get all leaf articles (excludeParents: true means only get articles, not category pages) @@ -143,21 +148,31 @@ export class DiscoveryLandingTransformer implements PageTransformer { // Apply includedCategories filter if specified if (discoveryPage.includedCategories && discoveryPage.includedCategories.length > 0) { const includedCategories = discoveryPage.includedCategories.map((c) => c.toLowerCase()) - // Filter tocItems before flattening to preserve category info - const filterByCategory = (items: typeof tocItems): typeof tocItems => { - return items.filter((item) => { - const itemCategories = (item.category || []).map((c: string) => c.toLowerCase()) - return itemCategories.some((cat) => includedCategories.includes(cat)) - }) + + // Build a map of href → category from the full tree + const categoryMap = new Map() + interface TocNode { + href: string + category?: string[] + childTocItems?: TocNode[] + } + function collectCategories(items: TocNode[]) { + for (const item of items) { + if (item.category && item.category.length > 0) { + categoryMap.set(item.href, item.category) + } + if (item.childTocItems) collectCategories(item.childTocItems) + } } + collectCategories(tocItems) - // Re-flatten with category filtering - const filteredTocItems = filterByCategory(flattenTocItemsWithCategory(tocItems)) - allArticles = filteredTocItems.map((item) => ({ - href: item.href, - title: item.title, - intro: item.intro, - })) + allArticles = allArticles.filter((item) => { + const itemCategories = (categoryMap.get(item.href) || []).map((c) => c.toLowerCase()) + return ( + itemCategories.length === 0 || + itemCategories.some((cat) => includedCategories.includes(cat)) + ) + }) } if (allArticles.length > 0) { @@ -178,36 +193,3 @@ export class DiscoveryLandingTransformer implements PageTransformer { } } } - -/** - * Helper to flatten TOC items while preserving category info for filtering - */ -interface TocItemWithCategory { - href: string - title: string - intro?: string - category?: string[] - childTocItems?: TocItemWithCategory[] -} - -function flattenTocItemsWithCategory(tocItems: TocItemWithCategory[]): TocItemWithCategory[] { - const result: TocItemWithCategory[] = [] - - function recurse(items: TocItemWithCategory[]) { - for (const item of items) { - const hasChildren = item.childTocItems && item.childTocItems.length > 0 - - // Only include leaf nodes (articles, not category pages) - if (!hasChildren) { - result.push(item) - } - - if (hasChildren) { - recurse(item.childTocItems!) - } - } - } - - recurse(tocItems) - return result -} diff --git a/src/article-api/transformers/secret-scanning-transformer.ts b/src/article-api/transformers/secret-scanning-transformer.ts index 8a97480dcd08..a5cf0e08bdb2 100644 --- a/src/article-api/transformers/secret-scanning-transformer.ts +++ b/src/article-api/transformers/secret-scanning-transformer.ts @@ -1,12 +1,11 @@ -import type { Context, Page, SecretScanningData } from '@/types' +import type { Context, Page } from '@/types' import type { PageTransformer } from './types' -import fs from 'fs' -import yaml from 'js-yaml' +import { load } from 'js-yaml' import path from 'path' -import { getVersionInfo } from '@/app/lib/constants' import { liquid, renderContent } from '@/content-render/index' import { allVersions } from '@/versions/lib/all-versions' import { loadTemplate } from '@/article-api/lib/load-template' +import { getSecretScanningData } from '@/secret-scanning/lib/get-secret-scanning-data' /** * Transformer for Secret Scanning pages. @@ -25,7 +24,8 @@ export class SecretScanningTransformer implements PageTransformer { const currentVersion = context.currentVersion if (!currentVersion) throw new Error('currentVersion is required') - const { isEnterpriseCloud, isEnterpriseServer } = getVersionInfo(currentVersion) + const isEnterpriseCloud = currentVersion.includes('cloud') + const isEnterpriseServer = currentVersion.includes('enterprise-server') const versionPath = isEnterpriseCloud ? 'ghec' : isEnterpriseServer @@ -35,15 +35,15 @@ export class SecretScanningTransformer implements PageTransformer { const secretScanningDir = path.join(process.cwd(), 'src/secret-scanning/data/pattern-docs') const filepath = path.join(secretScanningDir, versionPath, 'public-docs.yml') - if (fs.existsSync(filepath)) { - const data = yaml.load(fs.readFileSync(filepath, 'utf-8')) as SecretScanningData[] + try { + const data = await getSecretScanningData(filepath) // Process Liquid in values for (const entry of data) { // Only process Liquid for the hasValidityCheck field, as in the middleware if (typeof entry.hasValidityCheck === 'string' && entry.hasValidityCheck.includes('{%')) { // Render Liquid and parse as YAML to get correct boolean type - entry.hasValidityCheck = yaml.load( + entry.hasValidityCheck = load( await liquid.parseAndRender(entry.hasValidityCheck, context), ) as boolean } @@ -54,9 +54,12 @@ export class SecretScanningTransformer implements PageTransformer { } context.secretScanningData = data - } else { - // If the file does not exist, set to empty array to ensure predictable behavior - context.secretScanningData = [] + } catch (error) { + if ((error as NodeJS.ErrnoException).code === 'ENOENT') { + context.secretScanningData = [] + } else { + throw error + } } } diff --git a/src/content-render/unified/rewrite-asset-urls.ts b/src/content-render/unified/rewrite-asset-urls.ts index 547b00deb911..eb112d4ed7ea 100644 --- a/src/content-render/unified/rewrite-asset-urls.ts +++ b/src/content-render/unified/rewrite-asset-urls.ts @@ -2,6 +2,9 @@ import fs from 'fs' import type { Element, Node } from 'hast' import { visit } from 'unist-util-visit' +// Process-level cache for stat results — file sizes don't change between deploys. +const statCache = new Map() + // Matches any tags with an href that starts with `/assets/` or '/public/' function isAssetOrPublicImg(node: Node): node is Element { return ( @@ -35,25 +38,27 @@ function getNewSrc(node: Element): string | undefined { const src = node.properties?.src as string if (!src.startsWith('/')) return + const filePath = src.slice(1) + + // Check cache first — avoids repeated statSync for the same image + if (statCache.has(filePath)) { + const cachedSize = statCache.get(filePath) + if (!cachedSize) return + const split = src.split('/') + split.splice(2, 0, `cb-${cachedSize}`) + return split.join('/') + } + try { - const filePath = src.slice(1) const stats = fs.statSync(filePath) - // The size is not perfect but it's good enough. The size is - // very fast to pick up without needing to do a deep hashing of the - // image's content. It's perfectly possible that someone edits an - // image and it's size doesn't change. Although very unlikely. - // The slightest change to the image is more likely to either increase - // or decrease the image size by at least 1 byte. - // Also, because of this limitation, we're not confident to cache the - // image more than say 24h. But in the unlikely event that someone does - // edit an image and the size doesn't change, there's always the - // escape hatch that you can soft-purge all manual CDN surrogate keys. + statCache.set(filePath, stats.size || null) if (!stats.size) return const hash = `${stats.size}` const split = src.split('/') split.splice(2, 0, `cb-${hash}`) return split.join('/') } catch { + statCache.set(filePath, null) console.warn( `Failed to get a hash for ${src} ` + '(This is mostly harmless and can happen with outdated translations).', diff --git a/src/data-directory/lib/get-data.ts b/src/data-directory/lib/get-data.ts index 55118a8eaa40..fffa242f63d2 100644 --- a/src/data-directory/lib/get-data.ts +++ b/src/data-directory/lib/get-data.ts @@ -379,23 +379,6 @@ function memoize any>(func: T): T { if (!cache.has(key)) { cache.set(key, func(...args)) } - const value = cache.get(key) - // If what was stored in the cache is a mutable, this time, return - // a shallow copy. - // Otherwise, what *might* happen is this: - // - // > const getNames = memoize(() => ["peter", "tucker"]) - // > var names = getNames() - // > names.push("ashley") - // > var names2 = getNames() - // > names2.push("charlotte") - // > console.log(names2) - // - // ["peter", "tucker", "ashley", "charlotte"] - // - // Note that these are shallow copies only. - if (Array.isArray(value)) return [...value] - if (typeof value === 'object') return { ...value } - return value + return cache.get(key) }) as T } diff --git a/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/excluded-article.md b/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/excluded-article.md new file mode 100644 index 000000000000..7c35f2d6eb70 --- /dev/null +++ b/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/excluded-article.md @@ -0,0 +1,13 @@ +--- +title: Excluded Article +intro: "This article has the Advanced category and should be excluded." +versions: + fpt: "*" + ghes: "*" + ghec: "*" +category: + - Advanced +layout: inline +--- + +This article should not appear when filtering by Getting started. diff --git a/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/included-article.md b/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/included-article.md new file mode 100644 index 000000000000..9b2eacaed027 --- /dev/null +++ b/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/included-article.md @@ -0,0 +1,13 @@ +--- +title: Included Article +intro: "This article has the Getting started category and should be included." +versions: + fpt: "*" + ghes: "*" + ghec: "*" +category: + - Getting started +layout: inline +--- + +This article should appear when filtering by Getting started. diff --git a/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/index.md b/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/index.md new file mode 100644 index 000000000000..36fda4b95398 --- /dev/null +++ b/src/fixtures/fixtures/content/get-started/discovery-filtered/filtered-category/index.md @@ -0,0 +1,11 @@ +--- +title: Filtered Category +intro: "A test category for filtering." +versions: + fpt: "*" + ghes: "*" + ghec: "*" +children: + - /included-article + - /excluded-article +--- diff --git a/src/fixtures/fixtures/content/get-started/discovery-filtered/index.md b/src/fixtures/fixtures/content/get-started/discovery-filtered/index.md new file mode 100644 index 000000000000..4ffc177f9da1 --- /dev/null +++ b/src/fixtures/fixtures/content/get-started/discovery-filtered/index.md @@ -0,0 +1,15 @@ +--- +title: Discovery Filtered +intro: "A test page for discovery landing with includedCategories filtering." +versions: + fpt: "*" + ghes: "*" + ghec: "*" +layout: discovery-landing +includedCategories: + - Getting started +children: + - /filtered-category +--- + +This page tests includedCategories filtering on discovery landing pages. diff --git a/src/fixtures/fixtures/content/get-started/index.md b/src/fixtures/fixtures/content/get-started/index.md index e64ae2eced8b..3dd5930c13cc 100644 --- a/src/fixtures/fixtures/content/get-started/index.md +++ b/src/fixtures/fixtures/content/get-started/index.md @@ -47,6 +47,7 @@ children: - /article-grid-bespoke - /multi-carousel - /non-child-resolution + - /discovery-filtered communityRedirect: name: Provide HubGit Feedback href: 'https://hubgit.com/orgs/community/discussions/categories/get-started' diff --git a/src/fixtures/tests/footer.ts b/src/fixtures/tests/footer.ts index cfb61ee35559..2df4b449b796 100644 --- a/src/fixtures/tests/footer.ts +++ b/src/fixtures/tests/footer.ts @@ -13,11 +13,10 @@ describe('footer', () => { expect($('a#support').attr('href')).toBe('https://support.github.com') }) - test('leads to support on 404 pages', async () => { - // Important to use the prefix /en/ on the failing URL or else - // it will render a very basic plain text 404 response. - const $: CheerioAPI = await getDOM('/en/delicious-snacks/donuts.php', { allow404: true }) - expect($('a#support').attr('href')).toBe('https://support.github.com') + test('renders minimal 404 page', async () => { + // 404 pages now render a minimal HTML response without the full layout + const $ = await getDOM('/en/delicious-snacks/donuts.php', { allow404: true }) + expect($('p').text()).toContain('Page not found.') }) }) diff --git a/src/fixtures/tests/playwright-rendering.spec.ts b/src/fixtures/tests/playwright-rendering.spec.ts index 331cb2913a61..6ae060d97614 100644 --- a/src/fixtures/tests/playwright-rendering.spec.ts +++ b/src/fixtures/tests/playwright-rendering.spec.ts @@ -205,8 +205,8 @@ test('404 page renders correctly', async ({ page }) => { const response = await page.goto('/this-definitely-does-not-exist') expect(response?.status()).toBe(404) - // Check that the 404 page content is rendered - await expect(page.getByText(/It looks like this page doesn't exist/)).toBeVisible() + // 404 pages now render a minimal HTML response + await expect(page.getByText('Page not found.')).toBeVisible() }) test.describe('platform picker', () => { diff --git a/src/frame/lib/create-tree.ts b/src/frame/lib/create-tree.ts index 96227b716875..2c0a71b6149b 100644 --- a/src/frame/lib/create-tree.ts +++ b/src/frame/lib/create-tree.ts @@ -4,6 +4,8 @@ import fs from 'fs/promises' import PageClass from './page' import type { UnversionedTree, Page } from '@/types' +const isProduction = process.env.NODE_ENV === 'production' + export default async function createTree( originalPath: string, rootPath?: string, @@ -179,19 +181,12 @@ function equalArray(arr1: string[], arr2: string[]): boolean { } async function getMtime(filePath: string): Promise { - // Use mtimeMs, which is a regular floating point number, instead of the - // mtime which is a Date based on that same number. - // Otherwise, if we use the Date instances, we have to compare - // them using `oneDate.getTime() === anotherDate.getTime()`. - const { mtimeMs } = await fs.stat(filePath) - // The `mtimeMs` is a number like `1669827766942.7954` - // From the docs: - // "The timestamp indicating the last time this file was modified expressed - // in nanoseconds since the POSIX Epoch." - // But the number isn't actually all that important. We just need it to - // later be able to know if it changed. We round it to the nearest - // millisecond. - return Math.round(mtimeMs) + if (isProduction) { + // In production, skip the full stat but still verify existence + await fs.access(filePath) + return 1 + } + return Math.round((await fs.stat(filePath)).mtimeMs) } // Page class has dynamic frontmatter properties that aren't in the type definition diff --git a/src/frame/lib/page.ts b/src/frame/lib/page.ts index 1d5f33d2a75a..d9fcc9b76a6c 100644 --- a/src/frame/lib/page.ts +++ b/src/frame/lib/page.ts @@ -18,9 +18,10 @@ import { allTools } from '@/tools/lib/all-tools' import { renderContentWithFallback } from '@/languages/lib/render-with-fallback' import { deprecated, supported } from '@/versions/lib/enterprise-server-releases' import { allPlatforms } from '@/tools/lib/all-platforms' - import type { Context, FrontmatterVersions, FeaturedLinksExpanded } from '@/types' +const isProduction = process.env.NODE_ENV === 'production' + // We're going to check a lot of pages' "ID" (the first part of // the relativePath) against `productMap` to make sure it's valid. // To avoid having to do `Object.keys(productMap).includes(id)` @@ -146,8 +147,8 @@ class Page { }: ReadFileContentsResult = await readFileContents(fullPath) // Get file modification time - const stats = await fs.stat(fullPath) - const mtime = stats.mtimeMs + // Only used to quick reload local dev; not needed for production + const mtime = isProduction ? 1 : (await fs.stat(fullPath)).mtimeMs // The `|| ''` is for pages that are purely frontmatter. // So the `content` property will be `undefined`. diff --git a/src/frame/lib/read-file-contents.ts b/src/frame/lib/read-file-contents.ts index cb6a146e8406..f608a8d7b9e3 100644 --- a/src/frame/lib/read-file-contents.ts +++ b/src/frame/lib/read-file-contents.ts @@ -3,13 +3,20 @@ import fs from 'fs/promises' import encodeBracketedParentheses from './encode-bracketed-parentheses' import fm from './frontmatter' +// Only cache on production so content folks still see changes faster on local dev +const fmCache = + process.env.NODE_ENV === 'production' ? new Map>() : null + /** * Read only the frontmatter from file */ export default async function fmfromf(filepath: string): Promise> { - let fileContent: string = await fs.readFile(filepath, 'utf8') + const cached = fmCache?.get(filepath) + if (cached) return cached + let fileContent: string = await fs.readFile(filepath, 'utf8') fileContent = encodeBracketedParentheses(fileContent) - - return fm(fileContent, { filepath }) + const result = fm(fileContent, { filepath }) + fmCache?.set(filepath, result) + return result } diff --git a/src/frame/middleware/app-router-gateway.ts b/src/frame/middleware/app-router-gateway.ts deleted file mode 100644 index b84e4f3f5b4c..000000000000 --- a/src/frame/middleware/app-router-gateway.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { - isInvalidVersionedPath, - isJunkPath, - isVersionedPath, - shouldUseAppRouter, - stripLocalePrefix, -} from '@/app/lib/routing-patterns' -import { defaultCacheControl } from './cache-control' -import type { ExtendedRequest } from '@/types' -import type { NextFunction, Response } from 'express' -import { nextApp } from './next' - -export default function appRouterGateway(req: ExtendedRequest, res: Response, next: NextFunction) { - const path = req.path || req.url - const strippedPath = stripLocalePrefix(path) - - // Only intercept GET and HEAD requests - if (req.method !== 'GET' && req.method !== 'HEAD') { - return next() - } - - // Special case: Always intercept /empty-categories paths - if (strippedPath.endsWith('/empty-categories')) { - const pageFound = !!(req.context && req.context.page) - - if (shouldUseAppRouter(path, pageFound)) { - req.url = '/404' - res.status(404) - defaultCacheControl(res) - - // Only pass the original pathname - no other headers needed - res.setHeader('x-pathname', req.path) - - res.locals = res.locals || {} - res.locals.handledByAppRouter = true - return nextApp.getRequestHandler()(req, res) - } - } - - // Don't route static assets, API routes, valid versioned docs paths, or junk paths to App Router - if ( - path.startsWith('/_next/') || - path.startsWith('/_build') || - path.startsWith('/assets/') || - path.startsWith('/public/') || - path.startsWith('/api/') || - path === '/api' || - isJunkPath(path) || - (isVersionedPath(path) && - !isInvalidVersionedPath(path) && - !strippedPath.endsWith('/empty-categories')) || - path.includes('.css') || - path.includes('.js') || - path.includes('.map') || - path.includes('.ico') || - path.includes('.png') || - path.includes('.svg') || - path.endsWith('/manifest.json') || - path.endsWith('/robots.txt') || - path.endsWith('/llms.txt') || - path.endsWith('/_500') - ) { - return next() - } - - const pageFound = !!(req.context && req.context.page) - - if (shouldUseAppRouter(path, pageFound)) { - console.log(`[INFO] Using App Router for path: ${path} (pageFound: ${!!pageFound})`) - - const innerStrippedPath = stripLocalePrefix(path) - - // For 404 routes, always route to our 404 page - if (innerStrippedPath === '/404' || innerStrippedPath === '/_not-found' || !pageFound) { - req.url = '/404' - res.status(404) - defaultCacheControl(res) - } else { - // For other App Router routes, use the stripped path - const originalUrl = req.url - req.url = strippedPath + originalUrl.substring(req.path.length) - } - - // Only pass pathname for App Router context creation - res.setHeader('x-pathname', req.path) - - // Mark response as handled to prevent further middleware processing - res.locals = res.locals || {} - res.locals.handledByAppRouter = true - - return nextApp.getRequestHandler()(req, res) - } - - console.log(`[INFO] Using Pages Router for path: ${path}`) - return next() -} diff --git a/src/frame/middleware/helmet.ts b/src/frame/middleware/helmet.ts index f2979fab0776..302bd0688adf 100644 --- a/src/frame/middleware/helmet.ts +++ b/src/frame/middleware/helmet.ts @@ -1,4 +1,3 @@ -import { shouldUseAppRouter, isVersionedPath } from '@/app/lib/routing-patterns' import { isArchivedVersion } from '@/archives/lib/is-archived-version' import { languagePrefixPathRegex } from '@/languages/lib/languages-server' import versionSatisfiesRange from '@/versions/lib/version-satisfies-range' @@ -81,16 +80,10 @@ devDirs.scriptSrcAttr.push("'unsafe-inline'") const STATIC_DEPRECATED_OPTIONS = structuredClone(DEFAULT_OPTIONS) STATIC_DEPRECATED_OPTIONS.contentSecurityPolicy.directives.scriptSrc.push("'unsafe-inline'") -// App Router specific CSP that allows inline scripts for NextJS hydration -const APP_ROUTER_OPTIONS = structuredClone(DEFAULT_OPTIONS) -const appRouterDirs = APP_ROUTER_OPTIONS.contentSecurityPolicy.directives -appRouterDirs.scriptSrc.push("'unsafe-inline'") // Required for NextJS App Router hydration - const defaultHelmet = helmet(DEFAULT_OPTIONS) const nodeDeprecatedHelmet = helmet(NODE_DEPRECATED_OPTIONS) const staticDeprecatedHelmet = helmet(STATIC_DEPRECATED_OPTIONS) const developerDeprecatedHelmet = helmet(DEVELOPER_DEPRECATED_OPTIONS) -const appRouterHelmet = helmet(APP_ROUTER_OPTIONS) export default function helmetMiddleware(req: Request, res: Response, next: NextFunction) { // Enable CORS @@ -98,24 +91,6 @@ export default function helmetMiddleware(req: Request, res: Response, next: Next res.set('access-control-allow-origin', '*') } - // Check if this is an explicit App Router route - if (shouldUseAppRouter(req.path, true)) { - return appRouterHelmet(req, res, next) - } - - // For potential 404s that might be handled by App Router, use App Router CSP - // This is a safe fallback since App Router CSP includes all necessary permissions - // Apply to any path that could potentially be a 404, regardless of locale prefix - if ( - !req.path.startsWith('/_next/') && - !req.path.startsWith('/assets/') && - !req.path.startsWith('/api/') && - !isVersionedPath(req.path) - ) { - // This might be a 404 that gets routed to App Router, so use App Router CSP - return appRouterHelmet(req, res, next) - } - // Determine version for exceptions const { requestedVersion } = isArchivedVersion(req) diff --git a/src/frame/middleware/index.ts b/src/frame/middleware/index.ts index 871605038ba0..9dc2fd5b6adc 100644 --- a/src/frame/middleware/index.ts +++ b/src/frame/middleware/index.ts @@ -70,7 +70,6 @@ import safeRedirect from './safe-redirect' import { MAX_REQUEST_TIMEOUT } from '@/frame/lib/constants' import { initLoggerContext } from '@/observability/logger/lib/logger-context' import { getAutomaticRequestLogger } from '@/observability/logger/middleware/get-automatic-request-logger' -import appRouterGateway from './app-router-gateway' import urlDecode from './url-decode' const { NODE_ENV } = process.env @@ -242,9 +241,6 @@ export default function index(app: Express) { // Check for a dropped connection before proceeding app.use(haltOnDroppedConnection) - // *** Add App Router Gateway here - before heavy contextualizers *** - app.use(asyncMiddleware(appRouterGateway)) - // *** Rendering, 2xx responses *** app.use('/api', api) app.use('/llms.txt', llmsTxt) diff --git a/src/frame/middleware/manifest-json.ts b/src/frame/middleware/manifest-json.ts index 87b666fd2066..851ca6ce5f11 100644 --- a/src/frame/middleware/manifest-json.ts +++ b/src/frame/middleware/manifest-json.ts @@ -1,5 +1,5 @@ import type { NextFunction, Request, Response } from 'express' -import fs from 'fs' +import fs from 'fs/promises' import path from 'path' import { defaultCacheControl } from './cache-control' @@ -53,7 +53,7 @@ export default async function manifestJson(req: Request, res: Response, next: Ne } for (const icon of ICONS) { for (const sizes of path.basename(icon).match(/\d+x\d+/g) || []) { - const stats = fs.statSync(icon) + const stats = await fs.stat(icon) const split = icon.slice(1).split(path.sep) const hash = `${stats.size}` split.splice(2, 0, `cb-${hash}`) diff --git a/src/frame/middleware/render-page.ts b/src/frame/middleware/render-page.ts index e69dc99f8b30..efdbcc5ee895 100644 --- a/src/frame/middleware/render-page.ts +++ b/src/frame/middleware/render-page.ts @@ -43,11 +43,6 @@ function buildMiniTocItems(req: ExtendedRequest) { } export default async function renderPage(req: ExtendedRequest, res: Response) { - // Skip if App Router has already handled this request - if (res.locals?.handledByAppRouter) { - return - } - const { context } = req // This is a contextualizing the request so that when this `req` is diff --git a/src/frame/start-server.ts b/src/frame/start-server.ts index 21dc7ef42831..fca1713301e4 100644 --- a/src/frame/start-server.ts +++ b/src/frame/start-server.ts @@ -1,3 +1,8 @@ +// IMPORTANT: OTel tracing MUST be the first import. It patches Node.js +// built-ins (http, etc.) at load time via auto-instrumentation. +// Moving this after any framework import will silently break tracing. +import '@/observability/lib/tracing' + import http from 'http' import tcpPortUsed from 'tcp-port-used' diff --git a/src/frame/tests/server.ts b/src/frame/tests/server.ts index e1870a44505a..130ce22e771c 100644 --- a/src/frame/tests/server.ts +++ b/src/frame/tests/server.ts @@ -86,16 +86,7 @@ describe('server', () => { // Important to use the prefix /en/ on the failing URL or else // it will render a very basic plain text 404 response. const $ = await getDOM('/en/not-a-real-page', { allow404: true }) - expect($('h1').first().text()).toBe('Ooops!') - // Using type assertion because cheerio v1 types don't include text() on root - expect(($ as any).text().includes("It looks like this page doesn't exist.")).toBe(true) - expect( - ($ as any) - .text() - .includes( - 'We track these errors automatically, but if the problem persists please feel free to contact us.', - ), - ).toBe(true) + expect(($ as any).text()).toContain('Page not found.') expect($.res.statusCode).toBe(404) }) diff --git a/src/learning-track/lib/process-learning-tracks.ts b/src/learning-track/lib/process-learning-tracks.ts index c7e17ca47d5d..cd1ff360aa53 100644 --- a/src/learning-track/lib/process-learning-tracks.ts +++ b/src/learning-track/lib/process-learning-tracks.ts @@ -47,45 +47,36 @@ export default async function processLearningTracks( // Note: this will use the translated learning tracks and automatically // fall back to English if they don't exist on disk in the translation. - const track = getDataByLanguage( + const rawTrack = getDataByLanguage( `learning-tracks.${context.currentProduct}.${renderedTrackName}`, context.currentLanguage!, ) - if (!track) { + if (!rawTrack) { throw new Error(`No learning track called '${renderedTrackName}'.`) } - // If the current language isn't 'en' we need to prepare and have the - // English equivalent ready. - // We do this for two reasons: - // - // 1. For each learning-track .yml file (in data) always want the - // English values for `guides`, `versions`. - // Meaning, for the translated learning tracks we only keep the - // `title` and `description`. - // - // 2. When we attempt to render the translated learning tracks' - // `title` and `description`, if they are failing to render, - // we need to have the English `title` and `description` to - // fall back to. - // + // For translated tracks, always use English `guides` and `versions` + // (translations sometimes break Liquid in those fields). Keep translated + // `title` and `description` so we can render them with a fallback. let enTrack!: LearningTrackMetadata + let track: LearningTrackMetadata if (context.currentLanguage !== 'en') { enTrack = getDataByLanguage( `learning-tracks.${context.currentProduct}.${renderedTrackName}`, 'en', ) - // Sometimes the translations have more than just translated the - // `title` and `description`, but also things that don't make sense - // to translate like `guides` and `versions`. Always draw that - // from the English equivalent. - track.guides = enTrack.guides - track.versions = enTrack.versions + track = { + ...rawTrack, + guides: enTrack.guides, + versions: enTrack.versions, + } + } else { + track = rawTrack } // If there is no `versions` prop in the learning track frontmatter, assume the track should display in all versions. if (track.versions) { - const trackVersions = getApplicableVersions(track.versions) + const trackVersions = getApplicableVersions(track.versions as string) // If the current version is not included, do not display the track. if (!context.currentVersion || !trackVersions.includes(context.currentVersion)) { diff --git a/src/learning-track/middleware/learning-track.ts b/src/learning-track/middleware/learning-track.ts index 014e986621cc..82a54cf89fc8 100644 --- a/src/learning-track/middleware/learning-track.ts +++ b/src/learning-track/middleware/learning-track.ts @@ -27,11 +27,13 @@ export default async function learningTrack( const trackName = req.query.learn as string let trackProduct = req.context.currentProduct as string - const allLearningTracks = getDeepDataByLanguage( + const rawLearningTracks = getDeepDataByLanguage( 'learning-tracks', req.language!, ) as LearningTracks + let allLearningTracks = rawLearningTracks + if (req.language !== 'en') { // Don't trust the `.guides` from the translation. It too often has // broken Liquid (e.g. `{% ifversion fpt 또는 ghec 또는 ghes %}`) @@ -39,25 +41,23 @@ export default async function learningTrack( 'learning-tracks', 'en', ) as LearningTracks - for (const [key, tracks] of Object.entries(allLearningTracks)) { + // Build a filtered copy instead of mutating the cached original + const filtered: LearningTracks = {} + for (const [key, tracks] of Object.entries(rawLearningTracks)) { if (!(key in allEnglishLearningTracks)) { - // This can happen when the translation of - // `data/learning-tracks/foo.yml` has stuff in it that the English - // content no longer has. In that case, just skip it. - delete allLearningTracks[key] console.warn('No English learning track for %s', key) continue } + filtered[key] = {} for (const [name, track] of Object.entries(tracks)) { - // If this individual track does no longer exist in English, - // delete it from the translation too. - if (!(name in allEnglishLearningTracks[key])) { - delete tracks[name] - continue + if (!(name in allEnglishLearningTracks[key])) continue + filtered[key][name] = { + ...track, + guides: allEnglishLearningTracks[key][name].guides, } - track.guides = allEnglishLearningTracks[key][name].guides } } + allLearningTracks = filtered } let tracksPerProduct = allLearningTracks[trackProduct] diff --git a/src/observability/lib/tracing.browser.ts b/src/observability/lib/tracing.browser.ts new file mode 100644 index 000000000000..847629fc1ff8 --- /dev/null +++ b/src/observability/lib/tracing.browser.ts @@ -0,0 +1,3 @@ +// Browser stub for tracing.ts — OTel is server-only. +// This file is aliased in by Next.js webpack and Turbopack for client bundles. +// It's a no-op: tracing.ts is a side-effect-only module with no exports. diff --git a/src/observability/lib/tracing.ts b/src/observability/lib/tracing.ts new file mode 100644 index 000000000000..04cd8be9aee0 --- /dev/null +++ b/src/observability/lib/tracing.ts @@ -0,0 +1,53 @@ +// OpenTelemetry distributed tracing setup for docs-internal. +// +// Follows the same pattern as github/alloy and github/github-ui: +// - Conditional on OTEL_EXPORTER_OTLP_TRACES_ENDPOINT being set +// - OTLP/HTTP (proto) exporter to OTel Collector mesh +// - W3C Trace Context + Baggage propagation +// - Node auto-instrumentation for HTTP, Express, etc. +// +// References: +// - https://thehub.github.com/epd/engineering/dev-practicals/observability/distributed-tracing/ +// - https://thehub.github.com/epd/engineering/dev-practicals/observability/distributed-tracing/github-telemetry-js-user-guide/ + +import { + CompositePropagator, + W3CBaggagePropagator, + W3CTraceContextPropagator, +} from '@opentelemetry/core' +import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto' +import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node' +import { NodeSDK } from '@opentelemetry/sdk-node' + +// For tracing diagnostics, uncomment these lines: +// import { diag, DiagConsoleLogger, DiagLogLevel } from '@opentelemetry/api' +// diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.DEBUG) + +if (process.env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) { + const sdk = new NodeSDK({ + serviceName: process.env.OTEL_SERVICE_NAME || 'docs-internal', + traceExporter: new OTLPTraceExporter({}), + instrumentations: [getNodeAutoInstrumentations()], + textMapPropagator: new CompositePropagator({ + propagators: [new W3CTraceContextPropagator(), new W3CBaggagePropagator()], + }), + }) + + try { + sdk.start() + } catch (error) { + console.error('[tracing] failed to start:', error instanceof Error ? error.message : error) + } + + // Gracefully shut down the SDK on process exit. + // Uses `once` to prevent duplicate shutdown if SIGTERM is delivered multiple times. + process.once('SIGTERM', async () => { + try { + await sdk.shutdown() + } catch (error) { + if (error instanceof Error) { + console.error(`[tracing] shutdown error: ${error.message}`) + } + } + }) +} diff --git a/src/observability/middleware/handle-errors.ts b/src/observability/middleware/handle-errors.ts index b7e6acb4d11d..a5c5402ba5e4 100644 --- a/src/observability/middleware/handle-errors.ts +++ b/src/observability/middleware/handle-errors.ts @@ -3,6 +3,7 @@ import type { NextFunction, Response } from 'express' import FailBot from '../lib/failbot' import { shouldLogException, type ErrorWithCode } from '../lib/should-log-exception' import { nextApp } from '@/frame/middleware/next' +import { minimumNotFoundHtml } from '@/frame/lib/constants' import { setFastlySurrogateKey, SURROGATE_ENUMS } from '@/frame/middleware/set-fastly-surrogate-key' import { errorCacheControl } from '@/frame/middleware/cache-control' import statsd from '@/observability/lib/statsd' @@ -88,13 +89,10 @@ async function handleError( // Special handling for when a middleware calls `next(404)` if (error === 404) { - // Route to App Router for proper 404 handling - req.url = '/404' - res.status(404) - res.setHeader('x-pathname', req.path) - res.locals = res.locals || {} - res.locals.handledByAppRouter = true - return nextApp.getRequestHandler()(req, res) + errorCacheControl(res) + setFastlySurrogateKey(res, SURROGATE_ENUMS.DEFAULT) + res.status(404).type('html').send(minimumNotFoundHtml) + return } if (typeof error === 'number') { throw new Error("Don't use next(xxx) where xxx is any other number than 404") diff --git a/src/search/lib/helpers/get-client.ts b/src/search/lib/helpers/get-client.ts index b6b4c1106452..fcebb6ee19df 100644 --- a/src/search/lib/helpers/get-client.ts +++ b/src/search/lib/helpers/get-client.ts @@ -1,12 +1,21 @@ import { Client } from '@elastic/elasticsearch' import { safeUrlDisplay } from '@/search/lib/helpers/strings' -export function getElasticsearchClient(overrideURL = '', verbose = false): Client { +const DEFAULT_REQUEST_TIMEOUT = 5000 + +export function getElasticsearchClient( + overrideURL = '', + verbose = false, + options?: { requestTimeout?: number }, +): Client { const node = getElasticsearchURL(overrideURL) if (verbose) { console.log('Connecting to Elasticsearch URL:', safeUrlDisplay(node)) } - const client = new Client({ node }) + const client = new Client({ + node, + requestTimeout: options?.requestTimeout ?? DEFAULT_REQUEST_TIMEOUT, + }) return client } diff --git a/src/search/scripts/index/lib/index-ai-search-autocomplete.ts b/src/search/scripts/index/lib/index-ai-search-autocomplete.ts index 109514e04898..4f68943ccb33 100644 --- a/src/search/scripts/index/lib/index-ai-search-autocomplete.ts +++ b/src/search/scripts/index/lib/index-ai-search-autocomplete.ts @@ -26,7 +26,9 @@ type Options = { } export async function indexAISearchAutocomplete(options: Options) { - const client = getElasticsearchClient(undefined, options.verbose) + const client = getElasticsearchClient(undefined, options.verbose, { + requestTimeout: 5 * 60 * 1000, + }) await client.ping() // Will throw if not available console.log( diff --git a/src/search/scripts/index/lib/index-general-search.ts b/src/search/scripts/index/lib/index-general-search.ts index 7116794379e7..4da6a381a181 100644 --- a/src/search/scripts/index/lib/index-general-search.ts +++ b/src/search/scripts/index/lib/index-general-search.ts @@ -42,7 +42,9 @@ export async function indexGeneralSearch(sourceDirectory: string, opts: Options) throw new Error("Can't combine --language and --not-language") } - const client = getElasticsearchClient(opts.elasticsearchUrl, opts.verbose) + const client = getElasticsearchClient(opts.elasticsearchUrl, opts.verbose, { + requestTimeout: 5 * 60 * 1000, + }) await client.ping() // Will throw if not available let versions: string[] | 'all' = [] diff --git a/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml b/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml index c95af330cab3..034a6d18e02a 100644 --- a/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml +++ b/src/secret-scanning/data/pattern-docs/fpt/public-docs.yml @@ -4041,7 +4041,7 @@ secretType: salesforce_marketing_cloud_api_oauth2_token isPublic: false isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false diff --git a/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml b/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml index c95af330cab3..034a6d18e02a 100644 --- a/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml +++ b/src/secret-scanning/data/pattern-docs/ghec/public-docs.yml @@ -4041,7 +4041,7 @@ secretType: salesforce_marketing_cloud_api_oauth2_token isPublic: false isPrivateWithGhas: true - hasPushProtection: false + hasPushProtection: true hasValidityCheck: false hasExtendedMetadata: false base64Supported: false diff --git a/src/secret-scanning/lib/get-secret-scanning-data.ts b/src/secret-scanning/lib/get-secret-scanning-data.ts new file mode 100644 index 000000000000..f78a715adcc9 --- /dev/null +++ b/src/secret-scanning/lib/get-secret-scanning-data.ts @@ -0,0 +1,16 @@ +import fs from 'fs/promises' +import path from 'path' +import { load } from 'js-yaml' +import type { SecretScanningData } from '@/types' + +const cache = new Map() + +export async function getSecretScanningData(filepath: string): Promise { + const key = path.resolve(filepath) + if (cache.has(key)) return structuredClone(cache.get(key)!) + + const raw = await fs.readFile(key, 'utf-8') + const data = (load(raw) as SecretScanningData[]) ?? [] + cache.set(key, data) + return structuredClone(data) +} diff --git a/src/secret-scanning/middleware/secret-scanning.ts b/src/secret-scanning/middleware/secret-scanning.ts index 3f340c41271f..c72d4659c2aa 100644 --- a/src/secret-scanning/middleware/secret-scanning.ts +++ b/src/secret-scanning/middleware/secret-scanning.ts @@ -4,9 +4,9 @@ import yaml from 'js-yaml' import type { NextFunction, Response } from 'express' import { liquid } from '@/content-render/index' -import { ExtendedRequest, SecretScanningData } from '@/types' +import { ExtendedRequest } from '@/types' import { allVersions } from '@/versions/lib/all-versions' -import { getVersionInfo } from '@/app/lib/constants' +import { getSecretScanningData } from '@/secret-scanning/lib/get-secret-scanning-data' const secretScanningDir = 'src/secret-scanning/data/pattern-docs' @@ -28,7 +28,8 @@ export default async function secretScanning( const { currentVersion } = req.context if (!currentVersion) throw new Error('currentVersion not set in context') - const { isEnterpriseCloud, isEnterpriseServer } = getVersionInfo(currentVersion) + const isEnterpriseCloud = currentVersion.includes('cloud') + const isEnterpriseServer = currentVersion.includes('enterprise-server') if (isEnterpriseServer && !allVersions[currentVersion]) { return next() @@ -41,9 +42,7 @@ export default async function secretScanning( : 'fpt' const filepath = `${secretScanningDir}/${versionPath}/public-docs.yml` - req.context.secretScanningData = yaml.load( - fs.readFileSync(filepath, 'utf-8'), - ) as SecretScanningData[] + req.context.secretScanningData = await getSecretScanningData(filepath) // Some entries might use Liquid syntax, so we need // to execute that Liquid to get the actual value.