diff --git a/common/api-review/telemetry.api.md b/common/api-review/telemetry.api.md index 6c9dcdb93dc..5f863390da6 100644 --- a/common/api-review/telemetry.api.md +++ b/common/api-review/telemetry.api.md @@ -4,11 +4,12 @@ ```ts +import { AnyValueMap } from '@opentelemetry/api-logs'; import { FirebaseApp } from '@firebase/app'; import { LoggerProvider } from '@opentelemetry/sdk-logs'; // @public -export function captureError(telemetry: Telemetry, error: unknown): void; +export function captureError(telemetry: Telemetry, error: unknown, attributes?: AnyValueMap): void; // @public export function flush(telemetry: Telemetry): Promise; diff --git a/packages/telemetry/api-extractor.next.json b/packages/telemetry/api-extractor.next.json new file mode 100644 index 00000000000..0abb7e04f78 --- /dev/null +++ b/packages/telemetry/api-extractor.next.json @@ -0,0 +1,17 @@ +{ + "extends": "../../config/api-extractor.json", + "mainEntryPointFilePath": "/dist/src/next/index.d.ts", + "dtsRollup": { + "enabled": true, + "untrimmedFilePath": "/dist/next/index.d.ts" + }, + "apiReport": { + "enabled": false + }, + "docModel": { + "enabled": false + }, + "tsdocMetadata": { + "enabled": false + } +} diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json index b386b98ae0b..17cbfb26385 100644 --- a/packages/telemetry/package.json +++ b/packages/telemetry/package.json @@ -19,6 +19,11 @@ }, "default": "./dist/index.esm.js" }, + "./next": { + "types": "./dist/next/index.d.ts", + "import": "./dist/next/index.esm.js", + "require": "./dist/next/index.cjs.js" + }, "./package.json": "./package.json" }, "files": [ @@ -27,7 +32,7 @@ "scripts": { "lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", "lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'", - "build": "rollup -c && yarn api-report", + "build": "rollup -c && yarn api-report && yarn api-report:next", "build:deps": "lerna run --scope @firebase/telemetry --include-dependencies build", "dev": "rollup -c -w", "test": "run-p --npm-path npm lint test:all", @@ -37,6 +42,7 @@ "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha src/**/*.test.* --config ../../config/mocharc.node.js", "trusted-type-check": "tsec -p tsconfig.json --noEmit", "api-report": "api-extractor run --local --verbose", + "api-report:next": "api-extractor run --config api-extractor.next.json --local --verbose", "typings:public": "node ../../scripts/build/use_typings.js ./dist/telemetry-public.d.ts" }, "peerDependencies": { @@ -51,6 +57,7 @@ "@opentelemetry/resources": "2.0.1", "@opentelemetry/sdk-logs": "0.203.0", "@opentelemetry/semantic-conventions": "1.36.0", + "next": "15.5.2", "tslib": "^2.1.0" }, "license": "Apache-2.0", diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js index 6ce188cb72d..416f63fed0d 100644 --- a/packages/telemetry/rollup.config.js +++ b/packages/telemetry/rollup.config.js @@ -73,4 +73,41 @@ const nodeBuilds = [ } ]; -export default [...browserBuilds, ...nodeBuilds]; +const nextBuilds = [ + { + input: 'src/next/index.ts', + output: { + file: 'dist/next/index.esm.js', + format: 'es', + sourcemap: true + }, + plugins: [ + typescriptPlugin({ + typescript, + tsconfig: 'tsconfig.next.json', + useTsconfigDeclarationDir: true + }), + json() + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + }, + { + input: 'src/next/index.ts', + output: { + file: 'dist/next/index.cjs.js', + format: 'cjs', + sourcemap: true + }, + plugins: [ + typescriptPlugin({ + typescript, + tsconfig: 'tsconfig.next.json', + useTsconfigDeclarationDir: true + }), + json() + ], + external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`)) + } +]; + +export default [...browserBuilds, ...nodeBuilds, ...nextBuilds]; diff --git a/packages/telemetry/src/api.test.ts b/packages/telemetry/src/api.test.ts index 92e76c12429..ad13bc967ce 100644 --- a/packages/telemetry/src/api.test.ts +++ b/packages/telemetry/src/api.test.ts @@ -146,6 +146,34 @@ describe('Top level API', () => { 'logging.googleapis.com/spanId': `my-span` }); }); + + it('should propagate custom attributes', () => { + const error = new Error('This is a test error'); + error.stack = '...stack trace...'; + error.name = 'TestError'; + + captureError(fakeTelemetry, error, { + strAttr: 'string attribute', + mapAttr: { + boolAttr: true, + numAttr: 2 + }, + arrAttr: [1, 2, 3] + }); + + expect(emittedLogs.length).to.equal(1); + const log = emittedLogs[0]; + expect(log.attributes).to.deep.equal({ + 'error.type': 'TestError', + 'error.stack': '...stack trace...', + strAttr: 'string attribute', + mapAttr: { + boolAttr: true, + numAttr: 2 + }, + arrAttr: [1, 2, 3] + }); + }); }); describe('flush()', () => { diff --git a/packages/telemetry/src/api.ts b/packages/telemetry/src/api.ts index 9110310e1e5..27b785ff2a4 100644 --- a/packages/telemetry/src/api.ts +++ b/packages/telemetry/src/api.ts @@ -60,9 +60,14 @@ export function getTelemetry(app: FirebaseApp = getApp()): Telemetry { * @public * * @param telemetry - The {@link Telemetry} instance. - * @param error - the caught exception, typically an {@link Error} + * @param error - The caught exception, typically an {@link Error} + * @param attributes = Optional, arbitrary attributes to attach to the error log */ -export function captureError(telemetry: Telemetry, error: unknown): void { +export function captureError( + telemetry: Telemetry, + error: unknown, + attributes?: AnyValueMap +): void { const logger = telemetry.loggerProvider.getLogger('error-logger'); const activeSpanContext = trace.getActiveSpan()?.spanContext(); @@ -77,6 +82,8 @@ export function captureError(telemetry: Telemetry, error: unknown): void { } } + const customAttributes = attributes || {}; + if (error instanceof Error) { logger.emit({ severityNumber: SeverityNumber.ERROR, @@ -84,7 +91,8 @@ export function captureError(telemetry: Telemetry, error: unknown): void { attributes: { 'error.type': error.name || 'Error', 'error.stack': error.stack || 'No stack trace available', - ...traceAttributes + ...traceAttributes, + ...customAttributes } }); } else if (typeof error === 'string') { @@ -92,7 +100,8 @@ export function captureError(telemetry: Telemetry, error: unknown): void { severityNumber: SeverityNumber.ERROR, body: error, attributes: { - ...traceAttributes + ...traceAttributes, + ...customAttributes } }); } else { @@ -100,7 +109,8 @@ export function captureError(telemetry: Telemetry, error: unknown): void { severityNumber: SeverityNumber.ERROR, body: `Unknown error type: ${typeof error}`, attributes: { - ...traceAttributes + ...traceAttributes, + ...customAttributes } }); } diff --git a/packages/telemetry/src/next/index.test.ts b/packages/telemetry/src/next/index.test.ts new file mode 100644 index 00000000000..f9f2475a6b9 --- /dev/null +++ b/packages/telemetry/src/next/index.test.ts @@ -0,0 +1,80 @@ +/** + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { expect, use } from 'chai'; +import sinonChai from 'sinon-chai'; +import chaiAsPromised from 'chai-as-promised'; +import { restore, stub } from 'sinon'; +import { onRequestError } from './index'; +import * as app from '@firebase/app'; +import * as telemetry from '../api'; +import { FirebaseApp } from '@firebase/app'; +import { Telemetry } from '../public-types'; + +use(sinonChai); +use(chaiAsPromised); + +describe('onRequestError', () => { + let getTelemetryStub: sinon.SinonStub; + let captureErrorStub: sinon.SinonStub; + let fakeApp: FirebaseApp; + let fakeTelemetry: Telemetry; + + beforeEach(() => { + fakeApp = {} as FirebaseApp; + fakeTelemetry = {} as Telemetry; + + stub(app, 'getApp').returns(fakeApp); + getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry); + captureErrorStub = stub(telemetry, 'captureError'); + }); + + afterEach(() => { + restore(); + }); + + it('should capture errors with correct attributes', async () => { + const error = new Error('test error'); + const errorRequest = { + path: '/test-path?some=param', + method: 'GET', + headers: {} + }; + const errorContext: { + routerKind: 'Pages Router'; + routePath: string; + routeType: 'render'; + revalidateReason: undefined; + } = { + routerKind: 'Pages Router', + routePath: '/test-path', + routeType: 'render', + revalidateReason: undefined + }; + + await onRequestError(error, errorRequest, errorContext); + + expect(getTelemetryStub).to.have.been.calledOnceWith(fakeApp); + expect(captureErrorStub).to.have.been.calledOnceWith(fakeTelemetry, error, { + 'nextjs_path': '/test-path?some=param', + 'nextjs_method': 'GET', + 'nextjs_router_kind': 'Pages Router', + 'nextjs_route_path': '/test-path', + 'nextjs_route_type': 'render' + }); + }); +}); diff --git a/packages/telemetry/src/next/index.ts b/packages/telemetry/src/next/index.ts new file mode 100644 index 00000000000..81476e1db55 --- /dev/null +++ b/packages/telemetry/src/next/index.ts @@ -0,0 +1,53 @@ +/** + * @license + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { getApp } from '@firebase/app'; +import { captureError, getTelemetry } from '../api'; +import { type Instrumentation } from 'next'; +import { registerTelemetry } from '../register'; + +registerTelemetry(); + +/** + * Automatically report uncaught errors from server routes to Firebase Telemetry. + * + * @example + * ```javascript + * // In instrumentation.ts (https://nextjs.org/docs/app/guides/instrumentation): + * import { onRequestError as firebaseTelemetryOnRequestError } from '@firebase/telemetry/next'; + * export const onRequestError = firebaseTelemetryOnRequestError; + * ``` + * + * @public + */ +export const onRequestError: Instrumentation.onRequestError = async ( + error, + errorRequest, + errorContext +) => { + const telemetry = getTelemetry(getApp()); + + const attributes = { + 'nextjs_path': errorRequest.path, + 'nextjs_method': errorRequest.method, + 'nextjs_router_kind': errorContext.routerKind, + 'nextjs_route_path': errorContext.routePath, + 'nextjs_route_type': errorContext.routeType + }; + + captureError(telemetry, error, attributes); +}; diff --git a/packages/telemetry/tsconfig.next.json b/packages/telemetry/tsconfig.next.json new file mode 100644 index 00000000000..9dba66c5a74 --- /dev/null +++ b/packages/telemetry/tsconfig.next.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "declaration": true, + "declarationDir": "dist", + "rootDir": "./" + }, + "include": [ + "src/next/index.ts" + ] +} diff --git a/yarn.lock b/yarn.lock index 38577288673..dc226ade786 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,6 +1267,13 @@ resolved "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.2.16.tgz#df586341c8143ea997db0e51aae30c2dc1a634fa" integrity sha512-dCSHpoOKuTxecaYhWDRp2yFTN3XWcMPMrBVl5yOR8VZEUprz4+R3iuU7BipmlsqBnBDO/6l9H/C2ZwJdunkWyw== +"@emnapi/runtime@^1.4.4": + version "1.4.5" + resolved "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.5.tgz#c67710d0661070f38418b6474584f159de38aba9" + integrity sha512-++LApOtY0pEEz1zrd9vy1/zXVaVJJ/EbAF3u0fXIzPJEDtnITsBGbbK0EkM72amhl/R5b+5xx0Y/QhcVOpuulg== + dependencies: + tslib "^2.4.0" + "@eslint-community/eslint-utils@^4.2.0", "@eslint-community/eslint-utils@^4.4.0": version "4.4.1" resolved "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz#d1145bf2c20132d6400495d6df4bf59362fd9d56" @@ -1433,6 +1440,136 @@ resolved "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== +"@img/sharp-darwin-arm64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.34.3.tgz#4850c8ace3c1dc13607fa07d43377b1f9aa774da" + integrity sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg== + optionalDependencies: + "@img/sharp-libvips-darwin-arm64" "1.2.0" + +"@img/sharp-darwin-x64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.34.3.tgz#edf93fb01479604f14ad6a64a716e2ef2bb23100" + integrity sha512-yHpJYynROAj12TA6qil58hmPmAwxKKC7reUqtGLzsOHfP7/rniNGTL8tjWX6L3CTV4+5P4ypcS7Pp+7OB+8ihA== + optionalDependencies: + "@img/sharp-libvips-darwin-x64" "1.2.0" + +"@img/sharp-libvips-darwin-arm64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.2.0.tgz#e20e9041031acde1de19da121dc5162c7d2cf251" + integrity sha512-sBZmpwmxqwlqG9ueWFXtockhsxefaV6O84BMOrhtg/YqbTaRdqDE7hxraVE3y6gVM4eExmfzW4a8el9ArLeEiQ== + +"@img/sharp-libvips-darwin-x64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.2.0.tgz#918ca81c5446f31114834cb908425a7532393185" + integrity sha512-M64XVuL94OgiNHa5/m2YvEQI5q2cl9d/wk0qFTDVXcYzi43lxuiFTftMR1tOnFQovVXNZJ5TURSDK2pNe9Yzqg== + +"@img/sharp-libvips-linux-arm64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.2.0.tgz#1a5beafc857b43f378c3030427aa981ee3edbc54" + integrity sha512-RXwd0CgG+uPRX5YYrkzKyalt2OJYRiJQ8ED/fi1tq9WQW2jsQIn0tqrlR5l5dr/rjqq6AHAxURhj2DVjyQWSOA== + +"@img/sharp-libvips-linux-arm@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.2.0.tgz#bff51182d5238ca35c5fe9e9f594a18ad6a5480d" + integrity sha512-mWd2uWvDtL/nvIzThLq3fr2nnGfyr/XMXlq8ZJ9WMR6PXijHlC3ksp0IpuhK6bougvQrchUAfzRLnbsen0Cqvw== + +"@img/sharp-libvips-linux-ppc64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.2.0.tgz#10c53ccf6f2d47d71fb3fa282697072c8fe9e40e" + integrity sha512-Xod/7KaDDHkYu2phxxfeEPXfVXFKx70EAFZ0qyUdOjCcxbjqyJOEUpDe6RIyaunGxT34Anf9ue/wuWOqBW2WcQ== + +"@img/sharp-libvips-linux-s390x@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.2.0.tgz#392fd7557ddc5c901f1bed7ab3c567c08833ef3b" + integrity sha512-eMKfzDxLGT8mnmPJTNMcjfO33fLiTDsrMlUVcp6b96ETbnJmd4uvZxVJSKPQfS+odwfVaGifhsB07J1LynFehw== + +"@img/sharp-libvips-linux-x64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.2.0.tgz#9315cf90a2fdcdc0e29ea7663cbd8b0f15254400" + integrity sha512-ZW3FPWIc7K1sH9E3nxIGB3y3dZkpJlMnkk7z5tu1nSkBoCgw2nSRTFHI5pB/3CQaJM0pdzMF3paf9ckKMSE9Tg== + +"@img/sharp-libvips-linuxmusl-arm64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.2.0.tgz#705e03e67d477f6f842f37eb7f66285b1150dc06" + integrity sha512-UG+LqQJbf5VJ8NWJ5Z3tdIe/HXjuIdo4JeVNADXBFuG7z9zjoegpzzGIyV5zQKi4zaJjnAd2+g2nna8TZvuW9Q== + +"@img/sharp-libvips-linuxmusl-x64@1.2.0": + version "1.2.0" + resolved "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.2.0.tgz#ec905071cc538df64848d5900e0d386d77c55f13" + integrity sha512-SRYOLR7CXPgNze8akZwjoGBoN1ThNZoqpOgfnOxmWsklTGVfJiGJoC/Lod7aNMGA1jSsKWM1+HRX43OP6p9+6Q== + +"@img/sharp-linux-arm64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.34.3.tgz#476f8f13ce192555391ae9d4bc658637a6acf3e5" + integrity sha512-QdrKe3EvQrqwkDrtuTIjI0bu6YEJHTgEeqdzI3uWJOH6G1O8Nl1iEeVYRGdj1h5I21CqxSvQp1Yv7xeU3ZewbA== + optionalDependencies: + "@img/sharp-libvips-linux-arm64" "1.2.0" + +"@img/sharp-linux-arm@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.34.3.tgz#9898cd68ea3e3806b94fe25736d5d7ecb5eac121" + integrity sha512-oBK9l+h6KBN0i3dC8rYntLiVfW8D8wH+NPNT3O/WBHeW0OQWCjfWksLUaPidsrDKpJgXp3G3/hkmhptAW0I3+A== + optionalDependencies: + "@img/sharp-libvips-linux-arm" "1.2.0" + +"@img/sharp-linux-ppc64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.34.3.tgz#6a7cd4c608011333a0ddde6d96e03ac042dd9079" + integrity sha512-GLtbLQMCNC5nxuImPR2+RgrviwKwVql28FWZIW1zWruy6zLgA5/x2ZXk3mxj58X/tszVF69KK0Is83V8YgWhLA== + optionalDependencies: + "@img/sharp-libvips-linux-ppc64" "1.2.0" + +"@img/sharp-linux-s390x@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.34.3.tgz#48e27ab969efe97d270e39297654c0e0c9b42919" + integrity sha512-3gahT+A6c4cdc2edhsLHmIOXMb17ltffJlxR0aC2VPZfwKoTGZec6u5GrFgdR7ciJSsHT27BD3TIuGcuRT0KmQ== + optionalDependencies: + "@img/sharp-libvips-linux-s390x" "1.2.0" + +"@img/sharp-linux-x64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.34.3.tgz#5aa77ad4aa447ddf6d642e2a2c5599eb1292dfaa" + integrity sha512-8kYso8d806ypnSq3/Ly0QEw90V5ZoHh10yH0HnrzOCr6DKAPI6QVHvwleqMkVQ0m+fc7EH8ah0BB0QPuWY6zJQ== + optionalDependencies: + "@img/sharp-libvips-linux-x64" "1.2.0" + +"@img/sharp-linuxmusl-arm64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.34.3.tgz#62053a9d77c7d4632c677619325b741254689dd7" + integrity sha512-vAjbHDlr4izEiXM1OTggpCcPg9tn4YriK5vAjowJsHwdBIdx0fYRsURkxLG2RLm9gyBq66gwtWI8Gx0/ov+JKQ== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-arm64" "1.2.0" + +"@img/sharp-linuxmusl-x64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.34.3.tgz#5107c7709c7e0a44fe5abef59829f1de86fa0a3a" + integrity sha512-gCWUn9547K5bwvOn9l5XGAEjVTTRji4aPTqLzGXHvIr6bIDZKNTA34seMPgM0WmSf+RYBH411VavCejp3PkOeQ== + optionalDependencies: + "@img/sharp-libvips-linuxmusl-x64" "1.2.0" + +"@img/sharp-wasm32@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.34.3.tgz#c1dcabb834ec2f71308a810b399bb6e6e3b79619" + integrity sha512-+CyRcpagHMGteySaWos8IbnXcHgfDn7pO2fiC2slJxvNq9gDipYBN42/RagzctVRKgxATmfqOSulgZv5e1RdMg== + dependencies: + "@emnapi/runtime" "^1.4.4" + +"@img/sharp-win32-arm64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.34.3.tgz#3e8654e368bb349d45799a0d7aeb29db2298628e" + integrity sha512-MjnHPnbqMXNC2UgeLJtX4XqoVHHlZNd+nPt1kRPmj63wURegwBhZlApELdtxM2OIZDRv/DFtLcNhVbd1z8GYXQ== + +"@img/sharp-win32-ia32@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.34.3.tgz#9d4c105e8d5074a351a81a0b6d056e0af913bf76" + integrity sha512-xuCdhH44WxuXgOM714hn4amodJMZl3OEvf0GVTm0BEyMeA2to+8HEdRPShH0SLYptJY1uBw+SCFP9WVQi1Q/cw== + +"@img/sharp-win32-x64@0.34.3": + version "0.34.3" + resolved "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.34.3.tgz#d20c89bd41b1dd3d76d8575714aaaa3c43204b6a" + integrity sha512-OWwz05d++TxzLEv4VnsTz5CmZ6mI6S05sfQGEMrNrQcOEERbX46332IvE7pO/EUiw7jUrrS40z/M7kPyjfl04g== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -2298,6 +2435,51 @@ resolved "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.12.24.tgz#30728e34ebc90351dd3aff4e18d038eed2c3e098" integrity sha512-Mfmij13RUTmHEMi9vRUhMXD7rnGR2VvxeNYtaGtaJ4redwwjT4UXYJ+nzmVJF7hhd4pn/Fx5sncDKxMVFJSWPg== +"@next/env@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/env/-/env-15.5.2.tgz#0c6b959313cd6e71afb69bf0deb417237f1d2f8a" + integrity sha512-Qe06ew4zt12LeO6N7j8/nULSOe3fMXE4dM6xgpBQNvdzyK1sv5y4oAP3bq4LamrvGCZtmRYnW8URFCeX5nFgGg== + +"@next/swc-darwin-arm64@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-15.5.2.tgz#f69713326fc08f2eff3726fe19165cdb429d67c7" + integrity sha512-8bGt577BXGSd4iqFygmzIfTYizHb0LGWqH+qgIF/2EDxS5JsSdERJKA8WgwDyNBZgTIIA4D8qUtoQHmxIIquoQ== + +"@next/swc-darwin-x64@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-15.5.2.tgz#560a9da4126bae75cbbd6899646ad7a2e4fdcc9b" + integrity sha512-2DjnmR6JHK4X+dgTXt5/sOCu/7yPtqpYt8s8hLkHFK3MGkka2snTv3yRMdHvuRtJVkPwCGsvBSwmoQCHatauFQ== + +"@next/swc-linux-arm64-gnu@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-15.5.2.tgz#80b2be276e775e5a9286369ae54e536b0cdf8c3a" + integrity sha512-3j7SWDBS2Wov/L9q0mFJtEvQ5miIqfO4l7d2m9Mo06ddsgUK8gWfHGgbjdFlCp2Ek7MmMQZSxpGFqcC8zGh2AA== + +"@next/swc-linux-arm64-musl@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-15.5.2.tgz#68cf676301755fd99aca11a7ebdb5eae88d7c2e4" + integrity sha512-s6N8k8dF9YGc5T01UPQ08yxsK6fUow5gG1/axWc1HVVBYQBgOjca4oUZF7s4p+kwhkB1bDSGR8QznWrFZ/Rt5g== + +"@next/swc-linux-x64-gnu@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-15.5.2.tgz#209d9a79d0f2333544f863b0daca3f7e29f2eaff" + integrity sha512-o1RV/KOODQh6dM6ZRJGZbc+MOAHww33Vbs5JC9Mp1gDk8cpEO+cYC/l7rweiEalkSm5/1WGa4zY7xrNwObN4+Q== + +"@next/swc-linux-x64-musl@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-15.5.2.tgz#d4ad1cfb5e99e51db669fe2145710c1abeadbd7f" + integrity sha512-/VUnh7w8RElYZ0IV83nUcP/J4KJ6LLYliiBIri3p3aW2giF+PAVgZb6mk8jbQSB3WlTai8gEmCAr7kptFa1H6g== + +"@next/swc-win32-arm64-msvc@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-15.5.2.tgz#070e10e370a5447a198c2db100389646aca2c496" + integrity sha512-sMPyTvRcNKXseNQ/7qRfVRLa0VhR0esmQ29DD6pqvG71+JdVnESJaHPA8t7bc67KD5spP3+DOCNLhqlEI2ZgQg== + +"@next/swc-win32-x64-msvc@15.5.2": + version "15.5.2" + resolved "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-15.5.2.tgz#9237d40b82eaf2efc88baeba15b784d4126caf4a" + integrity sha512-W5VvyZHnxG/2ukhZF/9Ikdra5fdNftxI6ybeVKYvBPDtyx7x4jPPSNduUkfH5fo3zG0JQ0bPxgy41af2JX5D4Q== + "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -2941,6 +3123,13 @@ resolved "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz#821f8442f4175d8f0467b9daf26e3a18e2d02af2" integrity sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA== +"@swc/helpers@0.5.15": + version "0.5.15" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz#79efab344c5819ecf83a43f3f9f811fc84b516d7" + integrity sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g== + dependencies: + tslib "^2.8.0" + "@szmarczak/http-timer@^4.0.5": version "4.0.6" resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz#b4a914bb62e7c272d4e5989fe4440f812ab1d807" @@ -5137,6 +5326,11 @@ camelcase@^6.0.0, camelcase@^6.2.0: resolved "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== +caniuse-lite@^1.0.30001579: + version "1.0.30001737" + resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001737.tgz#8292bb7591932ff09e9a765f12fdf5629a241ccc" + integrity sha512-BiloLiXtQNrY5UyF0+1nSJLXUENuhka2pzy2Fx5pGxqavdrxSCW4U6Pn/PoG3Efspi2frRbHpBV2XsrPE6EDlw== + caniuse-lite@^1.0.30001688: version "1.0.30001731" resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001731.tgz" @@ -5415,6 +5609,11 @@ cli-width@^3.0.0: resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +client-only@0.0.1: + version "0.0.1" + resolved "https://registry.npmjs.org/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + cliui@^3.2.0: version "3.2.0" resolved "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" @@ -5558,7 +5757,7 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -color-string@^1.6.0: +color-string@^1.6.0, color-string@^1.9.0: version "1.9.1" resolved "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== @@ -5579,6 +5778,14 @@ color@^3.1.3: color-convert "^1.9.3" color-string "^1.6.0" +color@^4.2.3: + version "4.2.3" + resolved "https://registry.npmjs.org/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + colorette@^1.1.0: version "1.4.0" resolved "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" @@ -6438,6 +6645,11 @@ detect-libc@^2.0.0: resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz#f0cd503b40f9939b894697d19ad50895e30cf700" integrity sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw== +detect-libc@^2.0.4: + version "2.0.4" + resolved "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz#f04715b8ba815e53b4d8109655b6508a6865a7e8" + integrity sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA== + detect-newline@^2.0.0: version "2.1.0" resolved "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" @@ -11770,6 +11982,11 @@ nanoid@3.3.1: resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.1.tgz#6347a18cac88af88f58af0b3594b723d5e99bb35" integrity sha512-n6Vs/3KGyxPQd6uO0eH4Bv0ojGSUvuLlIHtC3Y0kEO23YRge8H9x1GCzLn28YX0H66pMkxuaeESFq4tKISKwdw== +nanoid@^3.3.6: + version "3.3.11" + resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz#4f4f112cefbe303202f2199838128936266d185b" + integrity sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w== + nanomatch@^1.2.9: version "1.2.13" resolved "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" @@ -11832,6 +12049,27 @@ next-tick@^1.1.0: resolved "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== +next@15.5.2: + version "15.5.2" + resolved "https://registry.npmjs.org/next/-/next-15.5.2.tgz#5e50102443fb0328a9dfcac2d82465c7bac93693" + integrity sha512-H8Otr7abj1glFhbGnvUt3gz++0AF1+QoCXEBmd/6aKbfdFwrn0LpA836Ed5+00va/7HQSDD+mOoVhn3tNy3e/Q== + dependencies: + "@next/env" "15.5.2" + "@swc/helpers" "0.5.15" + caniuse-lite "^1.0.30001579" + postcss "8.4.31" + styled-jsx "5.1.6" + optionalDependencies: + "@next/swc-darwin-arm64" "15.5.2" + "@next/swc-darwin-x64" "15.5.2" + "@next/swc-linux-arm64-gnu" "15.5.2" + "@next/swc-linux-arm64-musl" "15.5.2" + "@next/swc-linux-x64-gnu" "15.5.2" + "@next/swc-linux-x64-musl" "15.5.2" + "@next/swc-win32-arm64-msvc" "15.5.2" + "@next/swc-win32-x64-msvc" "15.5.2" + sharp "^0.34.3" + nise@^4.0.4: version "4.1.0" resolved "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz#8fb75a26e90b99202fa1e63f448f58efbcdedaf6" @@ -13185,6 +13423,15 @@ possible-typed-array-names@^1.0.0: resolved "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" integrity sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q== +postcss@8.4.31: + version "8.4.31" + resolved "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + postcss@^7.0.16: version "7.0.39" resolved "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" @@ -14509,6 +14756,11 @@ semver@^7.0.0, semver@^7.1.1, semver@^7.1.3, semver@^7.3.2, semver@^7.3.4, semve resolved "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== +semver@^7.7.2: + version "7.7.2" + resolved "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== + semver@~7.3.0: version "7.3.8" resolved "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" @@ -14642,6 +14894,38 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +sharp@^0.34.3: + version "0.34.3" + resolved "https://registry.npmjs.org/sharp/-/sharp-0.34.3.tgz#10a03bcd15fb72f16355461af0b9245ccb8a5da3" + integrity sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg== + dependencies: + color "^4.2.3" + detect-libc "^2.0.4" + semver "^7.7.2" + optionalDependencies: + "@img/sharp-darwin-arm64" "0.34.3" + "@img/sharp-darwin-x64" "0.34.3" + "@img/sharp-libvips-darwin-arm64" "1.2.0" + "@img/sharp-libvips-darwin-x64" "1.2.0" + "@img/sharp-libvips-linux-arm" "1.2.0" + "@img/sharp-libvips-linux-arm64" "1.2.0" + "@img/sharp-libvips-linux-ppc64" "1.2.0" + "@img/sharp-libvips-linux-s390x" "1.2.0" + "@img/sharp-libvips-linux-x64" "1.2.0" + "@img/sharp-libvips-linuxmusl-arm64" "1.2.0" + "@img/sharp-libvips-linuxmusl-x64" "1.2.0" + "@img/sharp-linux-arm" "0.34.3" + "@img/sharp-linux-arm64" "0.34.3" + "@img/sharp-linux-ppc64" "0.34.3" + "@img/sharp-linux-s390x" "0.34.3" + "@img/sharp-linux-x64" "0.34.3" + "@img/sharp-linuxmusl-arm64" "0.34.3" + "@img/sharp-linuxmusl-x64" "0.34.3" + "@img/sharp-wasm32" "0.34.3" + "@img/sharp-win32-arm64" "0.34.3" + "@img/sharp-win32-ia32" "0.34.3" + "@img/sharp-win32-x64" "0.34.3" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -14917,6 +15201,11 @@ sort-keys@^4.0.0: dependencies: is-plain-obj "^2.0.0" +source-map-js@^1.0.2: + version "1.2.1" + resolved "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== + source-map-loader@1.1.3: version "1.1.3" resolved "https://registry.npmjs.org/source-map-loader/-/source-map-loader-1.1.3.tgz#7dbc2fe7ea09d3e43c51fd9fc478b7f016c1f820" @@ -15457,6 +15746,13 @@ stubs@^3.0.0: resolved "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz#e8d2ba1fa9c90570303c030b6900f7d5f89abe5b" integrity sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw== +styled-jsx@5.1.6: + version "5.1.6" + resolved "https://registry.npmjs.org/styled-jsx/-/styled-jsx-5.1.6.tgz#83b90c077e6c6a80f7f5e8781d0f311b2fe41499" + integrity sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA== + dependencies: + client-only "0.0.1" + superstatic@^9.1.0: version "9.1.0" resolved "https://registry.npmjs.org/superstatic/-/superstatic-9.1.0.tgz#ef046c3bd4e8756e004168428a0c72f420491aba" @@ -16010,7 +16306,7 @@ tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.1, tslib@^2.1.0, tslib@^2.6.2: +tslib@^2.0.1, tslib@^2.1.0, tslib@^2.4.0, tslib@^2.6.2, tslib@^2.8.0: version "2.8.1" resolved "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz#612efe4ed235d567e8aba5f2a5fab70280ade83f" integrity sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==