diff --git a/common/api-review/telemetry-angular.api.md b/common/api-review/telemetry-angular.api.md
new file mode 100644
index 00000000000..b0078e25fc1
--- /dev/null
+++ b/common/api-review/telemetry-angular.api.md
@@ -0,0 +1,32 @@
+## API Report File for "@firebase/telemetry-angular"
+
+> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
+
+```ts
+
+import { ErrorHandler } from '@angular/core';
+import { FirebaseApp } from '@firebase/app';
+import { LoggerProvider } from '@opentelemetry/sdk-logs';
+
+// @public (undocumented)
+export class FirebaseErrorHandler implements ErrorHandler {
+ constructor(telemetryOptions?: TelemetryOptions | undefined);
+ // (undocumented)
+ handleError(error: unknown): void;
+ }
+
+// @public
+export interface Telemetry {
+ app: FirebaseApp;
+ loggerProvider: LoggerProvider;
+}
+
+// @public
+export interface TelemetryOptions {
+ endpointUrl?: string;
+}
+
+
+// (No @packageDocumentation comment for this package)
+
+```
diff --git a/docs-devsite/_toc.yaml b/docs-devsite/_toc.yaml
index 81078cb2618..edf5621e889 100644
--- a/docs-devsite/_toc.yaml
+++ b/docs-devsite/_toc.yaml
@@ -701,6 +701,15 @@ toc:
path: /docs/reference/js/telemetry_.telemetry.md
- title: TelemetryOptions
path: /docs/reference/js/telemetry_.telemetryoptions.md
+- title: telemetry/angular
+ path: /docs/reference/js/telemetry_angular.md
+ section:
+ - title: FirebaseErrorHandler
+ path: /docs/reference/js/telemetry_angular.firebaseerrorhandler.md
+ - title: Telemetry
+ path: /docs/reference/js/telemetry_angular.telemetry.md
+ - title: TelemetryOptions
+ path: /docs/reference/js/telemetry_angular.telemetryoptions.md
- title: telemetry/react
path: /docs/reference/js/telemetry_react.md
section:
diff --git a/docs-devsite/telemetry.md b/docs-devsite/telemetry.md
index c533e886f4f..8ddb78b2787 100644
--- a/docs-devsite/telemetry.md
+++ b/docs-devsite/telemetry.md
@@ -14,5 +14,6 @@ https://github.com/firebase/firebase-js-sdk
| Entry Point | Description |
| --- | --- |
| [/](./telemetry_.md#@firebase/telemetry) | |
+| [/angular](./telemetry_angular.md#@firebase/telemetry/angular) | |
| [/react](./telemetry_react.md#@firebase/telemetry/react) | |
diff --git a/docs-devsite/telemetry_angular.firebaseerrorhandler.md b/docs-devsite/telemetry_angular.firebaseerrorhandler.md
new file mode 100644
index 00000000000..11a115d9696
--- /dev/null
+++ b/docs-devsite/telemetry_angular.firebaseerrorhandler.md
@@ -0,0 +1,65 @@
+Project: /docs/reference/js/_project.yaml
+Book: /docs/reference/_book.yaml
+page_type: reference
+
+{% comment %}
+DO NOT EDIT THIS FILE!
+This is generated by the JS SDK team, and any local changes will be
+overwritten. Changes should be made in the source code at
+https://github.com/firebase/firebase-js-sdk
+{% endcomment %}
+
+# FirebaseErrorHandler class
+Signature:
+
+```typescript
+export declare class FirebaseErrorHandler implements ErrorHandler
+```
+Implements: ErrorHandler
+
+## Constructors
+
+| Constructor | Modifiers | Description |
+| --- | --- | --- |
+| [(constructor)(telemetryOptions)](./telemetry_angular.firebaseerrorhandler.md#firebaseerrorhandlerconstructor) | | Constructs a new instance of the FirebaseErrorHandler class |
+
+## Methods
+
+| Method | Modifiers | Description |
+| --- | --- | --- |
+| [handleError(error)](./telemetry_angular.firebaseerrorhandler.md#firebaseerrorhandlerhandleerror) | | |
+
+## FirebaseErrorHandler.(constructor)
+
+Constructs a new instance of the `FirebaseErrorHandler` class
+
+Signature:
+
+```typescript
+constructor(telemetryOptions?: TelemetryOptions | undefined);
+```
+
+#### Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| telemetryOptions | [TelemetryOptions](./telemetry_.telemetryoptions.md#telemetryoptions_interface) \| undefined | |
+
+## FirebaseErrorHandler.handleError()
+
+Signature:
+
+```typescript
+handleError(error: unknown): void;
+```
+
+#### Parameters
+
+| Parameter | Type | Description |
+| --- | --- | --- |
+| error | unknown | |
+
+Returns:
+
+void
+
diff --git a/docs-devsite/telemetry_angular.md b/docs-devsite/telemetry_angular.md
new file mode 100644
index 00000000000..bb341d2eb2e
--- /dev/null
+++ b/docs-devsite/telemetry_angular.md
@@ -0,0 +1,26 @@
+Project: /docs/reference/js/_project.yaml
+Book: /docs/reference/_book.yaml
+page_type: reference
+
+{% comment %}
+DO NOT EDIT THIS FILE!
+This is generated by the JS SDK team, and any local changes will be
+overwritten. Changes should be made in the source code at
+https://github.com/firebase/firebase-js-sdk
+{% endcomment %}
+
+# @firebase/telemetry/angular
+
+## Classes
+
+| Class | Description |
+| --- | --- |
+| [FirebaseErrorHandler](./telemetry_angular.firebaseerrorhandler.md#firebaseerrorhandler_class) | |
+
+## Interfaces
+
+| Interface | Description |
+| --- | --- |
+| [Telemetry](./telemetry_angular.telemetry.md#telemetry_interface) | An instance of the Firebase Telemetry SDK.Do not create this instance directly. Instead, use [getTelemetry()](./telemetry_.md#gettelemetry_448bdc6). |
+| [TelemetryOptions](./telemetry_angular.telemetryoptions.md#telemetryoptions_interface) | Options for initialized the Telemetry service using [getTelemetry()](./telemetry_.md#gettelemetry_448bdc6). |
+
diff --git a/docs-devsite/telemetry_angular.telemetry.md b/docs-devsite/telemetry_angular.telemetry.md
new file mode 100644
index 00000000000..d376755090d
--- /dev/null
+++ b/docs-devsite/telemetry_angular.telemetry.md
@@ -0,0 +1,48 @@
+Project: /docs/reference/js/_project.yaml
+Book: /docs/reference/_book.yaml
+page_type: reference
+
+{% comment %}
+DO NOT EDIT THIS FILE!
+This is generated by the JS SDK team, and any local changes will be
+overwritten. Changes should be made in the source code at
+https://github.com/firebase/firebase-js-sdk
+{% endcomment %}
+
+# Telemetry interface
+An instance of the Firebase Telemetry SDK.
+
+Do not create this instance directly. Instead, use [getTelemetry()](./telemetry_.md#gettelemetry_448bdc6).
+
+Signature:
+
+```typescript
+export interface Telemetry
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [app](./telemetry_angular.telemetry.md#telemetryapp) | [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) | The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance is associated with. |
+| [loggerProvider](./telemetry_angular.telemetry.md#telemetryloggerprovider) | LoggerProvider | The this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance uses. |
+
+## Telemetry.app
+
+The [FirebaseApp](./app.firebaseapp.md#firebaseapp_interface) this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance is associated with.
+
+Signature:
+
+```typescript
+app: FirebaseApp;
+```
+
+## Telemetry.loggerProvider
+
+The this [Telemetry](./telemetry_.telemetry.md#telemetry_interface) instance uses.
+
+Signature:
+
+```typescript
+loggerProvider: LoggerProvider;
+```
diff --git a/docs-devsite/telemetry_angular.telemetryoptions.md b/docs-devsite/telemetry_angular.telemetryoptions.md
new file mode 100644
index 00000000000..5a9075f49fa
--- /dev/null
+++ b/docs-devsite/telemetry_angular.telemetryoptions.md
@@ -0,0 +1,35 @@
+Project: /docs/reference/js/_project.yaml
+Book: /docs/reference/_book.yaml
+page_type: reference
+
+{% comment %}
+DO NOT EDIT THIS FILE!
+This is generated by the JS SDK team, and any local changes will be
+overwritten. Changes should be made in the source code at
+https://github.com/firebase/firebase-js-sdk
+{% endcomment %}
+
+# TelemetryOptions interface
+Options for initialized the Telemetry service using [getTelemetry()](./telemetry_.md#gettelemetry_448bdc6).
+
+Signature:
+
+```typescript
+export interface TelemetryOptions
+```
+
+## Properties
+
+| Property | Type | Description |
+| --- | --- | --- |
+| [endpointUrl](./telemetry_angular.telemetryoptions.md#telemetryoptionsendpointurl) | string | The URL for the endpoint to which telemetry data should be sent, in the Open Telemetry format. By default, data will be sent to Firebase. |
+
+## TelemetryOptions.endpointUrl
+
+The URL for the endpoint to which telemetry data should be sent, in the Open Telemetry format. By default, data will be sent to Firebase.
+
+Signature:
+
+```typescript
+endpointUrl?: string;
+```
diff --git a/packages/telemetry/api-extractor.json b/packages/telemetry/api-extractor.json
index 7bc55b00d75..e2abd62b21d 100644
--- a/packages/telemetry/api-extractor.json
+++ b/packages/telemetry/api-extractor.json
@@ -5,6 +5,10 @@
{
"modulePath": "react",
"filePath": "/dist/react/index.d.ts"
+ },
+ {
+ "modulePath": "angular",
+ "filePath": "/dist/angular/index.d.ts"
}
],
"dtsRollup": {
diff --git a/packages/telemetry/package.json b/packages/telemetry/package.json
index 084b15d03f8..0393651a3a4 100644
--- a/packages/telemetry/package.json
+++ b/packages/telemetry/package.json
@@ -31,6 +31,18 @@
},
"default": "./dist/react/index.esm.js"
},
+ "./angular": {
+ "types": "./dist/angular/index-public.d.ts",
+ "node": {
+ "import": "./dist/angular/index.esm.js",
+ "default": "./dist/angular/index.cjs.js"
+ },
+ "browser": {
+ "require": "./dist/angular/index.cjs.js",
+ "import": "./dist/angular/index.esm.js"
+ },
+ "default": "./dist/angular/index.esm.js"
+ },
"./package.json": "./package.json"
},
"files": [
@@ -39,6 +51,7 @@
"scripts": {
"lint": "eslint -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
"lint:fix": "eslint --fix -c .eslintrc.js '**/*.ts' --ignore-path '../../.gitignore'",
+ "build-only": "rollup -c",
"build": "rollup -c && yarn api-report",
"build:deps": "lerna run --scope @firebase/telemetry --include-dependencies build",
"dev": "rollup -c -w",
@@ -46,11 +59,12 @@
"test:ci": "node ../../scripts/run_tests_in_ci.js -s test:all",
"test:all": "run-p --npm-path npm test:browser test:node",
"test:browser": "karma start",
- "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --config ../../config/mocharc.node.js",
+ "test:node": "TS_NODE_COMPILER_OPTIONS='{\"module\":\"commonjs\"}' nyc --reporter lcovonly -- mocha **/*.test.ts src/**/*.test.ts --exclude src/angular/*.test.ts --config ../../config/mocharc.node.js",
"trusted-type-check": "tsec -p tsconfig.json --noEmit",
- "api-report": "yarn api-report:main && yarn api-report:react && yarn api-report:api-json",
+ "api-report": "yarn api-report:main && yarn api-report:react && yarn api-report:angular && yarn api-report:api-json",
"api-report:main": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry --packageRoot . --typescriptDts ./dist/index.d.ts --rollupDts ./dist/private.d.ts --untrimmedRollupDts ./dist/internal.d.ts --publicDts ./dist/index-public.d.ts",
"api-report:react": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry-react --packageRoot . --typescriptDts ./dist/react/index.d.ts --rollupDts ./dist/react/private.d.ts --untrimmedRollupDts ./dist/react/internal.d.ts --publicDts ./dist/react/index-public.d.ts",
+ "api-report:angular": "ts-node-script ../../repo-scripts/prune-dts/extract-public-api.ts --package telemetry-angular --packageRoot . --typescriptDts ./dist/angular/index.d.ts --rollupDts ./dist/angular/private.d.ts --untrimmedRollupDts ./dist/angular/internal.d.ts --publicDts ./dist/angular/index-public.d.ts",
"api-report:api-json": "api-extractor run --local --verbose",
"typings:public": "node ../../scripts/build/use_typings.js ./dist/index-public.d.ts"
},
@@ -66,6 +80,12 @@
},
"@types/react": {
"optional": true
+ },
+ "@angular/core": {
+ "optional": true
+ },
+ "@angular/router": {
+ "optional": true
}
},
"dependencies": {
@@ -82,6 +102,11 @@
},
"license": "Apache-2.0",
"devDependencies": {
+ "@angular/common": "19.2.15",
+ "@angular/compiler": "19.2.15",
+ "@angular/core": "19.2.15",
+ "@angular/platform-browser": "19.2.15",
+ "@angular/router": "19.2.15",
"@firebase/app": "0.14.4",
"@opentelemetry/sdk-trace-web": "2.1.0",
"@rollup/plugin-json": "6.1.0",
@@ -95,7 +120,9 @@
"rollup-plugin-copy": "3.5.0",
"rollup-plugin-replace": "2.2.0",
"rollup-plugin-typescript2": "0.36.0",
- "typescript": "5.5.4"
+ "rxjs": "7.8.2",
+ "typescript": "5.5.4",
+ "zone.js": "0.15.1"
},
"repository": {
"directory": "packages/telemetry",
diff --git a/packages/telemetry/rollup.config.js b/packages/telemetry/rollup.config.js
index a9a6df94188..5ffe3844148 100644
--- a/packages/telemetry/rollup.config.js
+++ b/packages/telemetry/rollup.config.js
@@ -123,4 +123,56 @@ const reactBuilds = [
}
];
-export default [...browserBuilds, ...nodeBuilds, ...reactBuilds];
+const angularBuilds = [
+ {
+ input: 'src/angular/index.ts',
+ output: {
+ file: pkg.exports['./angular'].browser.import,
+ format: 'es',
+ sourcemap: true
+ },
+ plugins: [
+ typescriptPlugin({
+ typescript,
+ tsconfig: 'tsconfig.angular.json'
+ }),
+ json(),
+ copy({
+ targets: [
+ {
+ src: 'dist/src/angular/index.d.ts',
+ dest: 'dist/angular'
+ },
+ {
+ src: 'dist/src/public-types.d.ts',
+ dest: 'dist'
+ }
+ ]
+ })
+ ],
+ external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
+ },
+ {
+ input: 'src/angular/index.ts',
+ output: {
+ file: pkg.exports['./angular'].browser.require,
+ format: 'cjs',
+ sourcemap: true
+ },
+ plugins: [
+ typescriptPlugin({
+ typescript,
+ tsconfig: 'tsconfig.angular.json'
+ }),
+ json()
+ ],
+ external: id => deps.some(dep => id === dep || id.startsWith(`${dep}/`))
+ }
+];
+
+export default [
+ ...browserBuilds,
+ ...nodeBuilds,
+ ...reactBuilds,
+ ...angularBuilds
+];
diff --git a/packages/telemetry/src/angular/index.test.ts b/packages/telemetry/src/angular/index.test.ts
new file mode 100644
index 00000000000..044467d93d4
--- /dev/null
+++ b/packages/telemetry/src/angular/index.test.ts
@@ -0,0 +1,110 @@
+/**
+ * @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 'zone.js';
+import 'zone.js/testing';
+import { expect, use } from 'chai';
+import sinonChai from 'sinon-chai';
+import chaiAsPromised from 'chai-as-promised';
+import { restore, stub } from 'sinon';
+import { FirebaseApp, deleteApp, initializeApp } from '@firebase/app';
+import * as telemetry from '../api';
+import {
+ Component,
+ Injector,
+ provideZoneChangeDetection,
+ runInInjectionContext
+} from '@angular/core';
+import { TestBed } from '@angular/core/testing';
+import { FirebaseErrorHandler } from '.';
+import { Telemetry } from '../public-types';
+import { Router, RouterModule } from '@angular/router';
+import {
+ BrowserTestingModule,
+ platformBrowserTesting
+} from '@angular/platform-browser/testing';
+
+use(sinonChai);
+use(chaiAsPromised);
+
+TestBed.initTestEnvironment(BrowserTestingModule, platformBrowserTesting());
+
+@Component({ template: '' })
+class DummyComponent {}
+
+describe('FirebaseErrorHandler', () => {
+ let errorHandler: FirebaseErrorHandler;
+ let router: Router;
+ let app: FirebaseApp;
+
+ let fakeTelemetry: Telemetry;
+
+ let captureErrorStub: sinon.SinonStub;
+ let getTelemetryStub: sinon.SinonStub;
+
+ beforeEach(() => {
+ app = initializeApp({ projectId: 'p', appId: 'fakeapp' });
+ fakeTelemetry = {} as Telemetry;
+
+ captureErrorStub = stub(telemetry, 'captureError');
+ getTelemetryStub = stub(telemetry, 'getTelemetry').returns(fakeTelemetry);
+
+ TestBed.configureTestingModule({
+ imports: [
+ RouterModule.forRoot([
+ { path: 'static-route', component: DummyComponent },
+ { path: 'dynamic/:id/route', component: DummyComponent }
+ ])
+ ],
+ providers: [provideZoneChangeDetection()]
+ });
+ const testInjector = TestBed.inject(Injector);
+ errorHandler = runInInjectionContext(
+ testInjector,
+ () => new FirebaseErrorHandler()
+ );
+ router = TestBed.inject(Router);
+ });
+
+ afterEach(async () => {
+ restore();
+ await deleteApp(app);
+ });
+
+ it('should log the error to the console', async () => {
+ await router.navigate(['/static-route']);
+
+ const testError = new Error('Test error message');
+ errorHandler.handleError(testError);
+ expect(getTelemetryStub).to.have.been.called;
+ expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, testError, {
+ 'angular_route_path': '/static-route'
+ });
+ });
+
+ it('should remove dynamic content from route', async () => {
+ await router.navigate(['/dynamic/my-name/route']);
+
+ const testError = new Error('Test error message');
+ errorHandler.handleError(testError);
+ expect(captureErrorStub).to.have.been.called;
+ expect(captureErrorStub).to.have.been.calledWith(fakeTelemetry, testError, {
+ // eslint-disable-next-line camelcase
+ angular_route_path: '/dynamic/:id/route'
+ });
+ });
+});
diff --git a/packages/telemetry/src/angular/index.ts b/packages/telemetry/src/angular/index.ts
new file mode 100644
index 00000000000..a761f46df9b
--- /dev/null
+++ b/packages/telemetry/src/angular/index.ts
@@ -0,0 +1,67 @@
+/**
+ * @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.
+ */
+
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { ErrorHandler, inject } from '@angular/core';
+// eslint-disable-next-line import/no-extraneous-dependencies
+import { ActivatedRouteSnapshot, Router } from '@angular/router';
+import { registerTelemetry } from '../register';
+import { captureError, getTelemetry } from '../api';
+import { TelemetryOptions } from '../public-types';
+import { getApp } from '@firebase/app';
+
+registerTelemetry();
+
+export * from '../public-types';
+
+export class FirebaseErrorHandler implements ErrorHandler {
+ private readonly router = inject(Router);
+
+ constructor(private telemetryOptions?: TelemetryOptions) {}
+
+ handleError(error: unknown): void {
+ const telemetry = getTelemetry(getApp(), this.telemetryOptions);
+
+ const attributes = {
+ 'angular_route_path': this.getSafeRoutePath(this.router)
+ };
+
+ captureError(telemetry, error, attributes);
+ }
+
+ /**
+ * Constructs the safe, templated route path from the router state.
+ * Example output: '/users/:id/posts'
+ */
+ private getSafeRoutePath(router: Router): string {
+ let currentRoute: ActivatedRouteSnapshot | null =
+ router.routerState.snapshot.root;
+
+ // Find the deepest activated child route
+ while (currentRoute.firstChild) {
+ currentRoute = currentRoute.firstChild;
+ }
+
+ // Traverse up from the deepest child to the root, collecting configured paths
+ const pathFromRoot = currentRoute.pathFromRoot
+ .map(route => route.routeConfig?.path)
+ .filter(path => path !== undefined && path !== '') // Filter out empty or undefined paths
+ .join('/');
+
+ return `/${pathFromRoot}`;
+ }
+}
diff --git a/packages/telemetry/src/api.test.ts b/packages/telemetry/src/api.test.ts
index 2085aa879f1..6a6c68deebf 100644
--- a/packages/telemetry/src/api.test.ts
+++ b/packages/telemetry/src/api.test.ts
@@ -29,7 +29,8 @@ import {
FirebaseApp,
initializeApp,
_registerComponent,
- _addOrOverwriteComponent
+ _addOrOverwriteComponent,
+ deleteApp
} from '@firebase/app';
import { Component, ComponentType } from '@firebase/component';
import { FirebaseAppCheckInternal } from '@firebase/app-check-interop-types';
@@ -70,9 +71,16 @@ const fakeTelemetry: Telemetry = {
};
describe('Top level API', () => {
+ let app: FirebaseApp;
+
beforeEach(() => {
// Clear the logs before each test.
emittedLogs.length = 0;
+ app = getFakeApp();
+ });
+
+ afterEach(async () => {
+ await deleteApp(app);
});
describe('getTelemetry()', () => {
diff --git a/packages/telemetry/src/react/index.test.tsx b/packages/telemetry/src/react/index.test.tsx
index 29643393133..44ede8922f9 100644
--- a/packages/telemetry/src/react/index.test.tsx
+++ b/packages/telemetry/src/react/index.test.tsx
@@ -30,7 +30,7 @@ import { render } from '@testing-library/react';
use(sinonChai);
use(chaiAsPromised);
-describe.only('FirebaseTelemetry', () => {
+describe('FirebaseTelemetry', () => {
let getTelemetryStub: sinon.SinonStub;
let captureErrorStub: sinon.SinonStub;
let initializeAppStub: sinon.SinonStub;
diff --git a/packages/telemetry/tsconfig.angular.json b/packages/telemetry/tsconfig.angular.json
new file mode 100644
index 00000000000..e870c27ba49
--- /dev/null
+++ b/packages/telemetry/tsconfig.angular.json
@@ -0,0 +1,8 @@
+{
+ "extends": "./tsconfig.json",
+ "compilerOptions": {
+ "outDir": "dist/angular",
+ "declarationDir": "dist/angular"
+ },
+ "include": ["src/angular/index.ts"]
+}
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index e6e4692d51e..a5e54f121ef 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -10,6 +10,41 @@
"@jridgewell/gen-mapping" "^0.3.5"
"@jridgewell/trace-mapping" "^0.3.24"
+"@angular/common@19.2.15":
+ version "19.2.15"
+ resolved "https://registry.npmjs.org/@angular/common/-/common-19.2.15.tgz#934d7ead5c8a3c4660ab131ba129fce6096def1d"
+ integrity sha512-aVa/ctBYH/4qgA7r4sS7TV+/DzRYmcS+3d6l89pNKUXkI8gpmsd+r3FjccaemX4Wqru1QOrMvC+i+e7IBIVv0g==
+ dependencies:
+ tslib "^2.3.0"
+
+"@angular/compiler@19.2.15":
+ version "19.2.15"
+ resolved "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.15.tgz#20fb21e77d6c6ace9a0c427a3ca9bcb4415b6336"
+ integrity sha512-hMHZU6/03xG0tbPDIm1hbVSTFLnRkGYfh+xdBwUMnIFYYTS0QJ2hdPfEZKCJIXm+fz9IAI5MPdDTfeyp0sgaHQ==
+ dependencies:
+ tslib "^2.3.0"
+
+"@angular/core@19.2.15":
+ version "19.2.15"
+ resolved "https://registry.npmjs.org/@angular/core/-/core-19.2.15.tgz#0395b60a8ef9c715a97df7a59fe4973ee3d35a51"
+ integrity sha512-PxhzCwwm23N4Mq6oV7UPoYiJF4r6FzGhRSxOBBlEp322k7zEQbIxd/XO6F3eoG73qC1UsOXMYYv6GnQpx42y3A==
+ dependencies:
+ tslib "^2.3.0"
+
+"@angular/platform-browser@19.2.15":
+ version "19.2.15"
+ resolved "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.15.tgz#efc814efd98f6e2b958f2a2588de862dcea364a0"
+ integrity sha512-OelQ6weCjon8kZD8kcqNzwugvZJurjS3uMJCwsA2vXmP/3zJ31SWtNqE2zLT1R2csVuwnp0h+nRMgq+pINU7Rg==
+ dependencies:
+ tslib "^2.3.0"
+
+"@angular/router@19.2.15":
+ version "19.2.15"
+ resolved "https://registry.npmjs.org/@angular/router/-/router-19.2.15.tgz#1d2748a9168a524d5ec8490849df2796bda0ab53"
+ integrity sha512-0TM1D8S7RQ00drKy7hA/ZLBY14dUBqFBgm06djcNcOjNzVAtgkeV0i+0Smq9tCC7UsGKdpZu4RgfYjHATBNlTQ==
+ dependencies:
+ tslib "^2.3.0"
+
"@apidevtools/json-schema-ref-parser@^9.0.3":
version "9.1.2"
resolved "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.1.2.tgz#8ff5386b365d4c9faa7c8b566ff16a46a577d9b8"
@@ -14700,6 +14735,13 @@ run-parallel@^1.1.9:
dependencies:
queue-microtask "^1.2.2"
+rxjs@7.8.2:
+ version "7.8.2"
+ resolved "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz#955bc473ed8af11a002a2be52071bf475638607b"
+ integrity sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==
+ dependencies:
+ tslib "^2.1.0"
+
rxjs@^6.3.3, rxjs@^6.5.1, rxjs@^6.6.0:
version "6.6.7"
resolved "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9"
@@ -16461,7 +16503,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.4.0, tslib@^2.6.2, tslib@^2.8.0:
+tslib@^2.0.1, tslib@^2.1.0, tslib@^2.3.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==
@@ -17870,3 +17912,8 @@ zip-stream@^6.0.1:
archiver-utils "^5.0.0"
compress-commons "^6.0.2"
readable-stream "^4.0.0"
+
+zone.js@0.15.1:
+ version "0.15.1"
+ resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz#1e109adb75f80e9e004ee8e0d4a0a52e0a336481"
+ integrity sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==