diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c44609b1e2c8..99ca517863ac 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1017,7 +1017,7 @@ jobs: 'generic-ts3.8', 'node-fastify-app', # TODO(v8): Re-enable hapi tests - # 'node-hapi-app', + 'node-hapi', 'node-nestjs-app', 'node-exports-test-app', 'node-koa-app', diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/tests/server.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi-app/tests/server.test.ts deleted file mode 100644 index d0c8c5d19fb7..000000000000 --- a/dev-packages/e2e-tests/test-applications/node-hapi-app/tests/server.test.ts +++ /dev/null @@ -1,208 +0,0 @@ -import { expect, test } from '@playwright/test'; -import { waitForError, waitForTransaction } from '@sentry-internal/event-proxy-server'; -import axios, { AxiosError } from 'axios'; - -const authToken = process.env.E2E_TEST_AUTH_TOKEN; -const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG; -const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT; -const EVENT_POLLING_TIMEOUT = 90_000; - -test('Sends captured exception to Sentry', async ({ baseURL }) => { - const { data } = await axios.get(`${baseURL}/test-error`); - const { exceptionId } = data; - - const url = `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${exceptionId}/`; - - console.log(`Polling for error eventId: ${exceptionId}`); - - await expect - .poll( - async () => { - try { - const response = await axios.get(url, { headers: { Authorization: `Bearer ${authToken}` } }); - - return response.status; - } catch (e) { - if (e instanceof AxiosError && e.response) { - if (e.response.status !== 404) { - throw e; - } else { - return e.response.status; - } - } else { - throw e; - } - } - }, - { timeout: EVENT_POLLING_TIMEOUT }, - ) - .toBe(200); -}); - -test('Sends thrown error to Sentry', async ({ baseURL }) => { - const errorEventPromise = waitForError('node-hapi-app', errorEvent => { - return errorEvent?.exception?.values?.[0]?.value === 'This is an error'; - }); - - try { - await axios.get(`${baseURL}/test-failure`); - } catch (e) {} - - const errorEvent = await errorEventPromise; - const errorEventId = errorEvent.event_id; - - await expect - .poll( - async () => { - try { - const response = await axios.get( - `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${errorEventId}/`, - { headers: { Authorization: `Bearer ${authToken}` } }, - ); - - return response.status; - } catch (e) { - if (e instanceof AxiosError && e.response) { - if (e.response.status !== 404) { - throw e; - } else { - return e.response.status; - } - } else { - throw e; - } - } - }, - { - timeout: EVENT_POLLING_TIMEOUT, - }, - ) - .toBe(200); -}); - -test('Sends successful transactions to Sentry', async ({ baseURL }) => { - const pageloadTransactionEventPromise = waitForTransaction('node-hapi-app', transactionEvent => { - return ( - transactionEvent?.contexts?.trace?.op === 'hapi.request' && transactionEvent?.transaction === '/test-success' - ); - }); - - await axios.get(`${baseURL}/test-success`); - - const transactionEvent = await pageloadTransactionEventPromise; - const transactionEventId = transactionEvent.event_id; - - await expect - .poll( - async () => { - try { - const response = await axios.get( - `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${transactionEventId}/`, - { headers: { Authorization: `Bearer ${authToken}` } }, - ); - - return response.status; - } catch (e) { - if (e instanceof AxiosError && e.response) { - if (e.response.status !== 404) { - throw e; - } else { - return e.response.status; - } - } else { - throw e; - } - } - }, - { - timeout: EVENT_POLLING_TIMEOUT, - }, - ) - .toBe(200); -}); - -test('sends error with parameterized transaction name', async ({ baseURL }) => { - const errorEventPromise = waitForError('node-hapi-app', errorEvent => { - return errorEvent?.exception?.values?.[0]?.value === 'This is an error with id 123'; - }); - - try { - await axios.get(`${baseURL}/test-error/123`); - } catch {} - - const errorEvent = await errorEventPromise; - - expect(errorEvent?.transaction).toBe('GET /test-error/{id}'); -}); - -test('Sends parameterized transactions to Sentry', async ({ baseURL }) => { - const pageloadTransactionEventPromise = waitForTransaction('node-hapi-app', transactionEvent => { - return ( - transactionEvent?.contexts?.trace?.op === 'hapi.request' && - transactionEvent?.transaction === '/test-param/{param}' - ); - }); - - await axios.get(`${baseURL}/test-param/123`); - - const transactionEvent = await pageloadTransactionEventPromise; - const transactionEventId = transactionEvent.event_id; - - expect(transactionEvent?.contexts?.trace?.op).toBe('hapi.request'); - expect(transactionEvent?.transaction).toBe('/test-param/{param}'); - - await expect - .poll( - async () => { - try { - const response = await axios.get( - `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${transactionEventId}/`, - { headers: { Authorization: `Bearer ${authToken}` } }, - ); - - return response.status; - } catch (e) { - if (e instanceof AxiosError && e.response) { - if (e.response.status !== 404) { - throw e; - } else { - return e.response.status; - } - } else { - throw e; - } - } - }, - { - timeout: EVENT_POLLING_TIMEOUT, - }, - ) - .toBe(200); -}); - -test('Sends sentry-trace and baggage as response headers', async ({ baseURL }) => { - const data = await axios.get(`${baseURL}/test-success`); - - expect(data.headers).toHaveProperty('sentry-trace'); - expect(data.headers).toHaveProperty('baggage'); -}); - -test('Continues trace and baggage from incoming headers', async ({ baseURL }) => { - const traceContent = '12312012123120121231201212312012-1121201211212012-0'; - const baggageContent = 'sentry-release=2.0.0,sentry-environment=myEnv'; - - await axios.get(`${baseURL}/test-success`); - - const data = await axios.get(`${baseURL}/test-success`, { - headers: { - 'sentry-trace': traceContent, - baggage: baggageContent, - }, - }); - - expect(data.headers).toHaveProperty('sentry-trace'); - expect(data.headers).toHaveProperty('baggage'); - - expect(data.headers['sentry-trace']).toContain('12312012123120121231201212312012-'); - expect(data.headers['baggage']).toContain(baggageContent); -}); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/.gitignore b/dev-packages/e2e-tests/test-applications/node-hapi/.gitignore similarity index 100% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/.gitignore rename to dev-packages/e2e-tests/test-applications/node-hapi/.gitignore diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/.npmrc b/dev-packages/e2e-tests/test-applications/node-hapi/.npmrc similarity index 100% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/.npmrc rename to dev-packages/e2e-tests/test-applications/node-hapi/.npmrc diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/package.json b/dev-packages/e2e-tests/test-applications/node-hapi/package.json similarity index 96% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/package.json rename to dev-packages/e2e-tests/test-applications/node-hapi/package.json index d63a3a6c457f..d0355205826c 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi-app/package.json +++ b/dev-packages/e2e-tests/test-applications/node-hapi/package.json @@ -1,5 +1,5 @@ { - "name": "node-hapi-app", + "name": "node-hapi", "version": "1.0.0", "private": true, "scripts": { diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/playwright.config.ts b/dev-packages/e2e-tests/test-applications/node-hapi/playwright.config.ts similarity index 100% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/playwright.config.ts rename to dev-packages/e2e-tests/test-applications/node-hapi/playwright.config.ts diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/src/app.js b/dev-packages/e2e-tests/test-applications/node-hapi/src/app.js similarity index 96% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/src/app.js rename to dev-packages/e2e-tests/test-applications/node-hapi/src/app.js index 6d6f959410dd..772847392e43 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi-app/src/app.js +++ b/dev-packages/e2e-tests/test-applications/node-hapi/src/app.js @@ -1,10 +1,4 @@ const Sentry = require('@sentry/node'); -const Hapi = require('@hapi/hapi'); - -const server = Hapi.server({ - port: 3030, - host: 'localhost', -}); Sentry.init({ environment: 'qa', // dynamic sampling bias to keep transactions @@ -15,6 +9,13 @@ Sentry.init({ tracesSampleRate: 1, }); +const Hapi = require('@hapi/hapi'); + +const server = Hapi.server({ + port: 3030, + host: 'localhost', +}); + const init = async () => { server.route({ method: 'GET', @@ -28,6 +29,8 @@ const init = async () => { method: 'GET', path: '/test-param/{param}', handler: function (request, h) { + Sentry.setTag(`param-${request.params.param}`, 'yes'); + return { paramWas: request.params.param }; }, }); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/start-event-proxy.ts b/dev-packages/e2e-tests/test-applications/node-hapi/start-event-proxy.ts similarity index 76% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/start-event-proxy.ts rename to dev-packages/e2e-tests/test-applications/node-hapi/start-event-proxy.ts index f1f5cf4b3316..25464165b311 100644 --- a/dev-packages/e2e-tests/test-applications/node-hapi-app/start-event-proxy.ts +++ b/dev-packages/e2e-tests/test-applications/node-hapi/start-event-proxy.ts @@ -2,5 +2,5 @@ import { startEventProxyServer } from '@sentry-internal/event-proxy-server'; startEventProxyServer({ port: 3031, - proxyServerName: 'node-hapi-app', + proxyServerName: 'node-hapi', }); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts new file mode 100644 index 000000000000..8782e8bb42a9 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/node-hapi/tests/errors.test.ts @@ -0,0 +1,95 @@ +import { expect, test } from '@playwright/test'; +import { waitForError } from '@sentry-internal/event-proxy-server'; +import axios, { AxiosError } from 'axios'; + +const authToken = process.env.E2E_TEST_AUTH_TOKEN; +const sentryTestOrgSlug = process.env.E2E_TEST_SENTRY_ORG_SLUG; +const sentryTestProject = process.env.E2E_TEST_SENTRY_TEST_PROJECT; +const EVENT_POLLING_TIMEOUT = 90_000; + +test('Sends captured exception to Sentry', async ({ baseURL }) => { + const { data } = await axios.get(`${baseURL}/test-error`); + const { exceptionId } = data; + + const url = `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${exceptionId}/`; + + console.log(`Polling for error eventId: ${exceptionId}`); + + await expect + .poll( + async () => { + try { + const response = await axios.get(url, { headers: { Authorization: `Bearer ${authToken}` } }); + + return response.status; + } catch (e) { + if (e instanceof AxiosError && e.response) { + if (e.response.status !== 404) { + throw e; + } else { + return e.response.status; + } + } else { + throw e; + } + } + }, + { timeout: EVENT_POLLING_TIMEOUT }, + ) + .toBe(200); +}); + +test('Sends thrown error to Sentry', async ({ baseURL }) => { + const errorEventPromise = waitForError('node-hapi', errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'This is an error'; + }); + + try { + await axios.get(`${baseURL}/test-failure`); + } catch (e) {} + + const errorEvent = await errorEventPromise; + const errorEventId = errorEvent.event_id; + + await expect + .poll( + async () => { + try { + const response = await axios.get( + `https://sentry.io/api/0/projects/${sentryTestOrgSlug}/${sentryTestProject}/events/${errorEventId}/`, + { headers: { Authorization: `Bearer ${authToken}` } }, + ); + + return response.status; + } catch (e) { + if (e instanceof AxiosError && e.response) { + if (e.response.status !== 404) { + throw e; + } else { + return e.response.status; + } + } else { + throw e; + } + } + }, + { + timeout: EVENT_POLLING_TIMEOUT, + }, + ) + .toBe(200); +}); + +test('sends error with parameterized transaction name', async ({ baseURL }) => { + const errorEventPromise = waitForError('node-hapi', errorEvent => { + return errorEvent?.exception?.values?.[0]?.value === 'This is an error with id 123'; + }); + + try { + await axios.get(`${baseURL}/test-error/123`); + } catch {} + + const errorEvent = await errorEventPromise; + + expect(errorEvent?.transaction).toBe('GET /test-error/{id}'); +}); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts new file mode 100644 index 000000000000..2c07128b6561 --- /dev/null +++ b/dev-packages/e2e-tests/test-applications/node-hapi/tests/transactions.test.ts @@ -0,0 +1,100 @@ +import { expect, test } from '@playwright/test'; +import { waitForTransaction } from '@sentry-internal/event-proxy-server'; +import axios from 'axios'; + +test('Sends successful transaction', async ({ baseURL }) => { + const pageloadTransactionEventPromise = waitForTransaction('node-hapi', transactionEvent => { + return ( + transactionEvent?.contexts?.trace?.op === 'http.server' && transactionEvent?.transaction === 'GET /test-success' + ); + }); + + await axios.get(`${baseURL}/test-success`); + + const transactionEvent = await pageloadTransactionEventPromise; + const transactionEventId = transactionEvent.event_id; + + expect(transactionEvent.contexts?.trace).toEqual({ + data: { + 'sentry.source': 'route', + 'sentry.origin': 'auto.http.otel.http', + 'sentry.op': 'http.server', + 'sentry.sample_rate': 1, + url: 'http://localhost:3030/test-success', + 'otel.kind': 'SERVER', + 'http.response.status_code': 200, + 'http.url': 'http://localhost:3030/test-success', + 'http.host': 'localhost:3030', + 'net.host.name': 'localhost', + 'http.method': 'GET', + 'http.scheme': 'http', + 'http.target': '/test-success', + 'http.user_agent': 'axios/1.6.7', + 'http.flavor': '1.1', + 'net.transport': 'ip_tcp', + 'net.host.ip': expect.any(String), + 'net.host.port': expect.any(Number), + 'net.peer.ip': expect.any(String), + 'net.peer.port': expect.any(Number), + 'http.status_code': 200, + 'http.status_text': 'OK', + 'http.route': '/test-success', + }, + op: 'http.server', + span_id: expect.any(String), + status: 'ok', + trace_id: expect.any(String), + origin: 'auto.http.otel.http', + }); + + expect(transactionEvent).toEqual( + expect.objectContaining({ + transaction: 'GET /test-success', + type: 'transaction', + transaction_info: { + source: 'route', + }, + }), + ); +}); + +test('Sends parameterized transactions to Sentry', async ({ baseURL }) => { + const pageloadTransactionEventPromise = waitForTransaction('node-hapi', transactionEvent => { + return ( + transactionEvent?.contexts?.trace?.op === 'http.server' && + transactionEvent?.transaction === 'GET /test-param/{param}' + ); + }); + + await axios.get(`${baseURL}/test-param/123`); + + const transactionEvent = await pageloadTransactionEventPromise; + const transactionEventId = transactionEvent.event_id; + + expect(transactionEvent?.contexts?.trace?.op).toBe('http.server'); + expect(transactionEvent?.contexts?.trace?.data?.['http.route']).toBe('/test-param/{param}'); + expect(transactionEvent?.transaction).toBe('GET /test-param/{param}'); +}); + +test('Isolates requests', async ({ baseURL }) => { + const transaction1Promise = waitForTransaction('node-hapi', transactionEvent => { + return ( + transactionEvent?.contexts?.trace?.op === 'http.server' && + transactionEvent?.contexts?.trace?.data?.['http.target'] === '/test-param/888' + ); + }); + const transaction2Promise = waitForTransaction('node-hapi', transactionEvent => { + return ( + transactionEvent?.contexts?.trace?.op === 'http.server' && + transactionEvent?.contexts?.trace?.data?.['http.target'] === '/test-param/999' + ); + }); + + await Promise.all([axios.get(`${baseURL}/test-param/888`), axios.get(`${baseURL}/test-param/999`)]); + + const transaction1 = await transaction1Promise; + const transaction2 = await transaction2Promise; + + expect(transaction1.tags).toEqual({ 'param-888': 'yes' }); + expect(transaction2.tags).toEqual({ 'param-999': 'yes' }); +}); diff --git a/dev-packages/e2e-tests/test-applications/node-hapi-app/tsconfig.json b/dev-packages/e2e-tests/test-applications/node-hapi/tsconfig.json similarity index 100% rename from dev-packages/e2e-tests/test-applications/node-hapi-app/tsconfig.json rename to dev-packages/e2e-tests/test-applications/node-hapi/tsconfig.json diff --git a/packages/node/package.json b/packages/node/package.json index 0c1df0bac414..18c447165676 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -61,7 +61,7 @@ "@opentelemetry/instrumentation-express": "0.35.0", "@opentelemetry/instrumentation-fastify": "0.35.0", "@opentelemetry/instrumentation-graphql": "0.39.0", - "@opentelemetry/instrumentation-hapi": "0.36.0", + "@opentelemetry/instrumentation-hapi": "0.38.0", "@opentelemetry/instrumentation-http": "0.51.0", "@opentelemetry/instrumentation-ioredis": "0.40.0", "@opentelemetry/instrumentation-koa": "0.39.0", diff --git a/yarn.lock b/yarn.lock index 3e8835911cdf..d8b5738feba5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4825,7 +4825,7 @@ dependencies: "@hapi/hoek" "9.x.x" -"@hapi/boom@^9.0.0", "@hapi/boom@^9.1.0": +"@hapi/boom@^9.1.0": version "9.1.4" resolved "https://registry.yarnpkg.com/@hapi/boom/-/boom-9.1.4.tgz#1f9dad367c6a7da9f8def24b4a986fc5a7bd9db6" integrity sha512-Ls1oH8jaN1vNsqcaHVYJrKmgMcKsC1wcp8bujvXrHaAqD2iDYq3HoOwsxwo09Cuda5R5nC0o0IxlrlTuvPuzSw== @@ -4933,7 +4933,7 @@ resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== -"@hapi/iron@6.x.x", "@hapi/iron@^6.0.0": +"@hapi/iron@6.x.x": version "6.0.0" resolved "https://registry.yarnpkg.com/@hapi/iron/-/iron-6.0.0.tgz#ca3f9136cda655bdd6028de0045da0de3d14436f" integrity sha512-zvGvWDufiTGpTJPG1Y/McN8UqWBu0k/xs/7l++HVU535NLHXsHhy54cfEMdW7EjwKfbBfM9Xy25FmTiobb7Hvw== @@ -4971,7 +4971,7 @@ "@hapi/hoek" "9.x.x" "@hapi/nigel" "4.x.x" -"@hapi/podium@4.x.x", "@hapi/podium@^4.1.1", "@hapi/podium@^4.1.3": +"@hapi/podium@4.x.x", "@hapi/podium@^4.1.1": version "4.1.3" resolved "https://registry.yarnpkg.com/@hapi/podium/-/podium-4.1.3.tgz#91e20838fc2b5437f511d664aabebbb393578a26" integrity sha512-ljsKGQzLkFqnQxE7qeanvgGj4dejnciErYd30dbrYzUOF/FyS/DOF97qcrT3bhoVwCYmxa6PEMhxfCPlnUcD2g== @@ -6227,15 +6227,14 @@ dependencies: "@opentelemetry/instrumentation" "^0.50.0" -"@opentelemetry/instrumentation-hapi@0.36.0": - version "0.36.0" - resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.36.0.tgz#ce3ed250ee0006f4335bda4cc06bc2d531307d4c" - integrity sha512-0NnXuRF89Windosn+iUpq5Fn/Foy8PMJxtLfe6CakDJIUGPj/g1+erz5irqSOc0P5mM3rEqKC/cYCoSIMKo/eA== +"@opentelemetry/instrumentation-hapi@0.38.0": + version "0.38.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.38.0.tgz#2913263248c190638aaed921b1f272af0b830a2b" + integrity sha512-ZcOqEuwuutTDYIjhDIStix22ECblG/i9pHje23QGs4Q4YS4RMaZ5hKCoQJxW88Z4K7T53rQkdISmoXFKDV8xMg== dependencies: "@opentelemetry/core" "^1.8.0" - "@opentelemetry/instrumentation" "^0.50.0" + "@opentelemetry/instrumentation" "^0.51.0" "@opentelemetry/semantic-conventions" "^1.0.0" - "@types/hapi__hapi" "20.0.13" "@opentelemetry/instrumentation-http@0.51.0": version "0.51.0" @@ -7082,23 +7081,6 @@ unplugin "1.0.1" uuid "^9.0.0" -"@sideway/address@^4.1.3": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" - integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== - dependencies: - "@hapi/hoek" "^9.0.0" - -"@sideway/formula@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" - integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== - -"@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== - "@sigstore/protobuf-specs@^0.1.0": version "0.1.0" resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.1.0.tgz#957cb64ea2f5ce527cc9cf02a096baeb0d2b99b4" @@ -8335,39 +8317,6 @@ dependencies: "@types/node" "*" -"@types/hapi__catbox@*": - version "10.2.5" - resolved "https://registry.yarnpkg.com/@types/hapi__catbox/-/hapi__catbox-10.2.5.tgz#4eb5e2fbb966acd2a3c2e86f935b7de95aceb7dd" - integrity sha512-vomIMP6dUDSbiasbPglH5LJvnnl8jFmRTjPgPl4l9Vi1L9fto3VXJQZtl8LzyIQUUoocyT5bmvWeYWsVgxAHQg== - -"@types/hapi__hapi@20.0.13": - version "20.0.13" - resolved "https://registry.yarnpkg.com/@types/hapi__hapi/-/hapi__hapi-20.0.13.tgz#ea8ce83c192f6e8106f6e76e40f795e7e36d0615" - integrity sha512-LP4IPfhIO5ZPVOrJo7H8c8Slc0WYTFAUNQX1U0LBPKyXioXhH5H2TawIgxKujIyOhbwoBbpvOsBf6o5+ToJIrQ== - dependencies: - "@hapi/boom" "^9.0.0" - "@hapi/iron" "^6.0.0" - "@hapi/podium" "^4.1.3" - "@types/hapi__catbox" "*" - "@types/hapi__mimos" "*" - "@types/hapi__shot" "*" - "@types/node" "*" - joi "^17.3.0" - -"@types/hapi__mimos@*": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/hapi__mimos/-/hapi__mimos-4.1.4.tgz#4f8a1c58345fc468553708d3cb508724aa081bd9" - integrity sha512-i9hvJpFYTT/qzB5xKWvDYaSXrIiNqi4ephi+5Lo6+DoQdwqPXQgmVVOZR+s3MBiHoFqsCZCX9TmVWG3HczmTEQ== - dependencies: - "@types/mime-db" "*" - -"@types/hapi__shot@*": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/hapi__shot/-/hapi__shot-4.1.4.tgz#17d418537bc180ac042361d9a331892a31a61583" - integrity sha512-AhEirOGy2ajtdV9WE/JqPkGeCH8lpgcSEQxn0ZNJkTvxkOv5DfZEXGit3l5J9P1VoQFAAHGNLVGWI5IWCiQf9A== - dependencies: - "@types/node" "*" - "@types/hast@^2.0.0": version "2.3.6" resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.6.tgz#bb8b05602112a26d22868acb70c4b20984ec7086" @@ -8550,11 +8499,6 @@ dependencies: "@types/unist" "*" -"@types/mime-db@*": - version "1.43.3" - resolved "https://registry.yarnpkg.com/@types/mime-db/-/mime-db-1.43.3.tgz#f7bec64a9a62ddded3371e82862c0516539710e8" - integrity sha512-vg0UsF1p1Qi/8iCARoie7F/Ng92zo7tQlL+sqE15GonkKVl55n/0vB6jSbrYTgDO0PSx9pKfGG1iZg9gJum3wA== - "@types/mime@*": version "3.0.4" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" @@ -20127,17 +20071,6 @@ jiti@^1.21.0: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== -joi@^17.3.0: - version "17.11.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" - integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.1" - "@sideway/pinpoint" "^2.0.0" - js-cleanup@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/js-cleanup/-/js-cleanup-1.2.0.tgz#8dbc65954b1d38b255f1e8cf02cd17b3f7a053f9"