Skip to content

Commit

Permalink
fix: add secondary entry points
Browse files Browse the repository at this point in the history
EmmanuelRoux committed Sep 2, 2023
1 parent 84d6b83 commit 89f9344
Showing 57 changed files with 310 additions and 244 deletions.
31 changes: 27 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -28,8 +28,9 @@

<hr>

**Note: this library was previously distributed as `@ngx-matomo/tracker` and `@ngx-matomo/router` packages. Since version 5, it is now distributed as a single package `ngx-matomo-client`.
Follow [instructions below](#migration-from-version--4-ngx-matomotracker-and-ngx-matomorouter) for how to
**Note: this library was previously distributed as `@ngx-matomo/tracker` and `@ngx-matomo/router` packages. Since
version 5, it is now distributed as a single package `ngx-matomo-client`.
Follow [instructions below](#migration-from-ngx-matomotracker-and-ngx-matomorouter-version--4) for how to
easily migrate.**

[![NPM version](https://img.shields.io/npm/v/@ngx-matomo/tracker/latest.svg?logo=npm&logoColor=fff&label=Legacy+NPM+package&color=limegreen)](https://www.npmjs.com/package/@ngx-matomo/tracker)
@@ -65,6 +66,7 @@ easily migrate.**
- [Migration from `@ngx-matomo/tracker` and `@ngx-matomo/router` (version <= 4)](#migration-from-ngx-matomotracker-and-ngx-matomorouter-version--4)
- [Configuration reference](#configuration-reference)
- [FAQ](#faq)
* [How to use `ngx-matomo-client` without `@angular/router`?](#how-to-use-ngx-matomo-client-without-angularrouter)
* [How to set page title?](#how-to-set-page-title)
* [Should I include the tracking code provided by Matomo?](#should-i-include-the-tracking-code-provided-by-matomo)
* [How to disable tracking in some environments?](#how-to-disable-tracking-in-some-environments)
@@ -147,6 +149,12 @@ Take a look at [configuration reference](#configuration-reference) for all avail

</details>

> **Note:** in this documentation, all code examples use imports from `ngx-matomo-client` because this is the most
> common use case.
> **If you don't have `@angular/router` in you application, you must import from `ngx-matomo-client/core` instead.**
>
> See [FAQ](#how-to-use-ngx-matomo-client-without-angularrouter) for more details.
## Usage

### Tracking page views
@@ -630,14 +638,29 @@ To manually migrate your code:
2. In your `package.json`, remove `@ngx-matomo/router` dependency
3. Replace all imports from `@ngx-matomo/tracker` or `@ngx-matomo/router` with imports from `ngx-matomo-client` instead.

Also, feel free to use the new `NgModule`-free way of providing `ngx-matomo-client` using `provideMatomo()` function instead of importing `NgxMatomoModule` and `NgxMatomoRouterModule`.
Also, feel free to use the new `NgModule`-free way of providing `ngx-matomo-client` using `provideMatomo()` function
instead of importing `NgxMatomoModule` and `NgxMatomoRouterModule`.

## Configuration reference

[Find all options and features here](docs/configuration-reference.md)

## FAQ

### How to use `ngx-matomo-client` without `@angular/router`?

If you don't have `@angular/router` in your application, you will encounter errors when declaring imports
from `ngx-matomo-client`.

**Instead, you must use imports from `ngx-matomo-client/core`.**

> This is because `ngx-matomo-client` is composed of two entry points:
>
> - `ngx-matomo-client/core` which contains core features and doesn't depend on `@angular/router`
> - `ngx-matomo-client/router` which brings router features and depends on `@angular/router`
>
> The global entrypoint `ngx-matomo-client` is simply a shorthand that re-exports all of them (thus depending on `@angular/router`).
### How to set page title?

If automatic page view tracking is enabled, then you probably have nothing to do: the page title will be detected and
@@ -803,7 +826,7 @@ import {
)
],
})
export class AppModule { }
export class AppModule {}
```

</td>
4 changes: 2 additions & 2 deletions angular.json
Original file line number Diff line number Diff line change
@@ -6,7 +6,7 @@
"ngx-matomo-client": {
"projectType": "library",
"root": "projects/ngx-matomo-client",
"sourceRoot": "projects/ngx-matomo-client/src",
"sourceRoot": "projects/ngx-matomo-client",
"prefix": "matomo",
"architect": {
"build": {
@@ -25,7 +25,7 @@
"test": {
"builder": "@angular-devkit/build-angular:karma",
"options": {
"main": "projects/ngx-matomo-client/src/test.ts",
"main": "projects/ngx-matomo-client/test.ts",
"tsConfig": "projects/ngx-matomo-client/tsconfig.spec.json",
"karmaConfig": "projects/ngx-matomo-client/karma.conf.js"
}
File renamed without changes.
1 change: 1 addition & 0 deletions projects/ngx-matomo-client/core/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './public-api';
6 changes: 6 additions & 0 deletions projects/ngx-matomo-client/core/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "public-api.ts"
}
}
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@ import { EnvironmentProviders, ModuleWithProviders, NgModule } from '@angular/co
import { MatomoOptOutFormComponent } from './directives/matomo-opt-out-form.component';
import { MatomoTrackClickDirective } from './directives/matomo-track-click.directive';
import { MatomoTrackerDirective } from './directives/matomo-tracker.directive';
import { MatomoFeature, provideMatomo, withScriptFactory } from './ngx-matomo-providers';
import { MatomoFeature, provideMatomo, withScriptFactory } from './providers';
import { MatomoConfiguration } from './tracker/configuration';
import { MatomoScriptFactory } from './tracker/script-factory';

7 changes: 7 additions & 0 deletions projects/ngx-matomo-client/core/private-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export { runOnce as ɵrunOnce } from './utils/function';
export { MATOMO_ROUTER_ENABLED as ɵMATOMO_ROUTER_ENABLED } from './tracker/configuration';
export {
createMatomoFeature as ɵcreateMatomoFeature,
MatomoFeatureKind as ɵMatomoFeatureKind,
MatomoFeature as ɵMatomoFeature,
} from './providers';
71 changes: 71 additions & 0 deletions projects/ngx-matomo-client/core/providers.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { ApplicationInitStatus, InjectionToken } from '@angular/core';
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import { provideMatomo, withScriptFactory } from './providers';
import { MATOMO_CONFIGURATION, MatomoConfiguration } from './tracker/configuration';
import { MatomoInitializerService } from './tracker/matomo-initializer.service';
import { MatomoTracker } from './tracker/matomo-tracker.service';
import { createDefaultMatomoScriptElement } from './tracker/script-factory';

describe('providers', () => {
async function setUp(providers: TestModuleMetadata['providers']): Promise<void> {
TestBed.configureTestingModule({
providers: providers,
});

// https://github.com/angular/angular/issues/24218
await TestBed.inject(ApplicationInitStatus).donePromise;
}

it('should provide basic Matomo providers with static configuration', async () => {
const fakeInitializer = jasmine.createSpyObj<MatomoInitializerService>(['initialize']);
const config: MatomoConfiguration = { trackerUrl: 'my-tracker', siteId: 42 };

await setUp([
{
provide: MatomoInitializerService,
useValue: fakeInitializer,
},
provideMatomo(config),
]);

expect(TestBed.inject(MatomoTracker)).toEqual(jasmine.any(MatomoTracker));
expect(TestBed.inject(MATOMO_CONFIGURATION)).toEqual(config);
expect(fakeInitializer.initialize).toHaveBeenCalledTimes(1);
});

it('should provide basic Matomo providers with configuration factory', async () => {
const fakeInitializer = jasmine.createSpyObj<MatomoInitializerService>(['initialize']);
const trackerUrl = 'my-tracker';
const config: MatomoConfiguration = { trackerUrl, siteId: 42 };
const trackerUrlToken = new InjectionToken<string>('trackerUrl');

await setUp([
{
provide: MatomoInitializerService,
useValue: fakeInitializer,
},
{
provide: trackerUrlToken,
useValue: trackerUrl,
},
provideMatomo(() => ({ trackerUrl: TestBed.inject(trackerUrlToken), siteId: 42 })),
]);

expect(TestBed.inject(MatomoTracker)).toEqual(jasmine.any(MatomoTracker));
expect(TestBed.inject(MATOMO_CONFIGURATION)).toEqual(config);
expect(fakeInitializer.initialize).toHaveBeenCalledTimes(1);
});

it('should provide basic Matomo providers with custom script factory', async () => {
const scriptFactory = jasmine
.createSpy('scriptFactory')
.and.callFake(createDefaultMatomoScriptElement);

await setUp([
provideMatomo({ trackerUrl: 'my-tracker', siteId: 42 }, withScriptFactory(scriptFactory)),
]);

expect(TestBed.inject(MatomoTracker)).toEqual(jasmine.any(MatomoTracker));
expect(scriptFactory).toHaveBeenCalledTimes(1);
});
});
Original file line number Diff line number Diff line change
@@ -4,24 +4,8 @@ import {
inject,
makeEnvironmentProviders,
Provider,
Type,
} from '@angular/core';
import { MATOMO_ROUTER_CONFIGURATION, MatomoRouterConfiguration } from './router/configuration';
import {
MatomoRouterInterceptor,
provideInterceptor,
provideInterceptors,
} from './router/interceptor';
import {
MATOMO_ROUTE_DATA_KEY,
MatomoRouteDataInterceptor,
} from './router/interceptors/route-data-interceptor';
import { MatomoRouter } from './router/matomo-router.service';
import {
MATOMO_CONFIGURATION,
MATOMO_ROUTER_ENABLED,
MatomoConfiguration,
} from './tracker/configuration';
import { MATOMO_CONFIGURATION, MatomoConfiguration } from './tracker/configuration';
import { MatomoInitializerService } from './tracker/matomo-initializer.service';
import { MATOMO_SCRIPT_FACTORY, MatomoScriptFactory } from './tracker/script-factory';

@@ -46,7 +30,7 @@ export interface MatomoFeature {
[PRIVATE_MATOMO_PROVIDERS]: Provider[];
}

function createMatomoFeature(kind: MatomoFeatureKind, providers: Provider[]): MatomoFeature {
export function createMatomoFeature(kind: MatomoFeatureKind, providers: Provider[]): MatomoFeature {
return { kind, [PRIVATE_MATOMO_PROVIDERS]: providers };
}

@@ -137,46 +121,3 @@ export function withScriptFactory(scriptFactory: MatomoScriptFactory): MatomoFea
{ provide: MATOMO_SCRIPT_FACTORY, useValue: scriptFactory },
]);
}

/** Enable automatic page views tracking */
export function withRouter(config?: MatomoRouterConfiguration): MatomoFeature {
const providers = [
{ provide: MATOMO_ROUTER_ENABLED, useValue: true },
{ provide: MATOMO_ROUTER_CONFIGURATION, useValue: config },
{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useValue() {
inject(MatomoRouter).initialize();
},
},
];

return createMatomoFeature(MatomoFeatureKind.Router, providers);
}

/** Add some matomo router interceptors */
export function withRouterInterceptors(
interceptors: Type<MatomoRouterInterceptor>[]
): MatomoFeature {
return createMatomoFeature(
MatomoFeatureKind.RouterInterceptors,
provideInterceptors(interceptors)
);
}

/**
* Enable retrieval of tracking information from route data
*
* @see MatomoRouteData
* @param key A custom key to get lookup route data - default is 'matomo'
*/
export function withRouteData(key?: string): MatomoFeature {
const providers: Provider[] = [provideInterceptor(MatomoRouteDataInterceptor)];

if (key) {
providers.push({ provide: MATOMO_ROUTE_DATA_KEY, useValue: key });
}

return createMatomoFeature(MatomoFeatureKind.BuiltInRouteDataInterceptor, providers);
}
34 changes: 34 additions & 0 deletions projects/ngx-matomo-client/core/public-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Public API Surface of tracker
*/

export * from './private-api';

export { NgxMatomoModule, NgxMatomoTrackerModule, MATOMO_DIRECTIVES } from './ngx-matomo.module';
export { provideMatomo, withScriptFactory, MatomoFeatureKind, MatomoFeature } from './providers';
export {
MatomoTracker,
MatomoECommerceItem,
MatomoECommerceView,
MatomoECommerceItemView,
MatomoECommerceCategoryView,
PagePerformanceTimings,
} from './tracker/matomo-tracker.service';
export { MatomoInitializerService } from './tracker/matomo-initializer.service';
export {
MatomoConfiguration,
MATOMO_CONFIGURATION,
AutoMatomoConfiguration,
MatomoInitializationMode,
MatomoConsentMode,
InternalMatomoConfiguration,
INTERNAL_MATOMO_CONFIGURATION,
} from './tracker/configuration';
export {
MATOMO_SCRIPT_FACTORY,
MatomoScriptFactory,
createDefaultMatomoScriptElement,
} from './tracker/script-factory';
export { MatomoTrackerDirective } from './directives/matomo-tracker.directive';
export { MatomoTrackClickDirective } from './directives/matomo-track-click.directive';
export { MatomoOptOutFormComponent } from './directives/matomo-opt-out-form.component';
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { EnvironmentInjector, PLATFORM_ID, Provider } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { MatomoHolder } from '../holder';
import { provideMatomo, withScriptFactory } from '../ngx-matomo-providers';
import { provideMatomo, withScriptFactory } from '../providers';
import {
MATOMO_CONFIGURATION,
MATOMO_ROUTER_ENABLED,
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
import { inject, InjectionToken, Type } from '@angular/core';
import {
INTERNAL_MATOMO_CONFIGURATION,
InternalMatomoConfiguration,
} from '../tracker/configuration';
import { INTERNAL_MATOMO_CONFIGURATION, InternalMatomoConfiguration } from 'ngx-matomo-client/core';
import { MatomoRouterInterceptor } from './interceptor';

export const MATOMO_ROUTER_CONFIGURATION = new InjectionToken<MatomoRouterConfiguration>(
File renamed without changes.
1 change: 1 addition & 0 deletions projects/ngx-matomo-client/router/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './public-api';
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import {
RouterState,
RouterStateSnapshot,
} from '@angular/router';
import { MatomoECommerceItemView, MatomoTracker } from '../../tracker/matomo-tracker.service';
import { MatomoECommerceItemView, MatomoTracker } from 'ngx-matomo-client/core';
import {
DEFAULT_DATA_KEY,
MatomoRouteData,
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inject, Injectable, InjectionToken } from '@angular/core';
import { ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs';
import { MatomoECommerceView, MatomoTracker } from '../../tracker/matomo-tracker.service';
import { MatomoECommerceView, MatomoTracker } from 'ngx-matomo-client/core';
import { MatomoRouteInterceptorBase } from './route-interceptor-base';

export const DEFAULT_DATA_KEY = 'matomo';
Original file line number Diff line number Diff line change
@@ -2,8 +2,7 @@ import { Provider } from '@angular/core';
import { fakeAsync, flush, TestBed, tick } from '@angular/core/testing';
import { Event, NavigationEnd, Router } from '@angular/router';
import { of, Subject } from 'rxjs';
import { MATOMO_CONFIGURATION } from '../tracker/configuration';
import { MatomoTracker } from '../tracker/matomo-tracker.service';
import { MATOMO_CONFIGURATION, MatomoTracker } from 'ngx-matomo-client/core';
import {
InternalGlobalConfiguration,
MATOMO_ROUTER_CONFIGURATION,
Original file line number Diff line number Diff line change
@@ -21,8 +21,7 @@ import {
take,
tap,
} from 'rxjs/operators';
import { MatomoTracker } from '../tracker/matomo-tracker.service';
import { runOnce } from '../utils/function';
import { MatomoTracker, ɵrunOnce as runOnce } from 'ngx-matomo-client/core';
import {
ExclusionConfig,
INTERNAL_ROUTER_CONFIGURATION,
6 changes: 6 additions & 0 deletions projects/ngx-matomo-client/router/ng-package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"$schema": "../../../node_modules/ng-packagr/ng-package.schema.json",
"lib": {
"entryFile": "public-api.ts"
}
}
Original file line number Diff line number Diff line change
@@ -2,10 +2,10 @@ import { ModuleWithProviders, NgModule, Optional, SkipSelf } from '@angular/core
import {
MATOMO_ROUTER_CONFIGURATION,
MatomoRouterConfigurationWithInterceptors,
} from './router/configuration';
import { provideInterceptors } from './router/interceptor';
import { MatomoRouter } from './router/matomo-router.service';
import { MATOMO_ROUTER_ENABLED } from './tracker/configuration';
} from './configuration';
import { provideInterceptors } from './interceptor';
import { MatomoRouter } from './matomo-router.service';
import { ɵMATOMO_ROUTER_ENABLED as MATOMO_ROUTER_ENABLED } from 'ngx-matomo-client/core';

@NgModule({
providers: [{ provide: MATOMO_ROUTER_ENABLED, useValue: true }],
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { APP_BASE_HREF, PlatformLocation } from '@angular/common';
import { TestBed } from '@angular/core/testing';
import { NavigationEnd } from '@angular/router';
import { MATOMO_CONFIGURATION, MatomoConfiguration } from '../tracker/configuration';
import { MATOMO_CONFIGURATION, MatomoConfiguration } from 'ngx-matomo-client/core';
import { MATOMO_ROUTER_CONFIGURATION, MatomoRouterConfiguration } from './configuration';
import { MATOMO_PAGE_URL_PROVIDER, PageUrlProvider } from './page-url-provider';

Original file line number Diff line number Diff line change
@@ -1,28 +1,19 @@
import { ApplicationInitStatus, InjectionToken } from '@angular/core';
import { ApplicationInitStatus } from '@angular/core';
import { TestBed, TestModuleMetadata } from '@angular/core/testing';
import {
provideMatomo,
withRouteData,
withRouter,
withRouterInterceptors,
withScriptFactory,
} from './ngx-matomo-providers';
import { MATOMO_ROUTER_CONFIGURATION } from './router/configuration';
import { MATOMO_ROUTER_INTERCEPTORS, MatomoRouterInterceptor } from './router/interceptor';
import { withRouteData, withRouter, withRouterInterceptors } from './providers';
import { MATOMO_ROUTER_CONFIGURATION } from './configuration';
import { MATOMO_ROUTER_INTERCEPTORS, MatomoRouterInterceptor } from './interceptor';
import {
DEFAULT_DATA_KEY,
MATOMO_ROUTE_DATA_KEY,
MatomoRouteDataInterceptor,
} from './router/interceptors/route-data-interceptor';
import { MatomoRouter } from './router/matomo-router.service';
} from './interceptors/route-data-interceptor';
import { MatomoRouter } from './matomo-router.service';
import {
MATOMO_CONFIGURATION,
MATOMO_ROUTER_ENABLED,
MatomoConfiguration,
} from './tracker/configuration';
import { MatomoInitializerService } from './tracker/matomo-initializer.service';
import { MatomoTracker } from './tracker/matomo-tracker.service';
import { createDefaultMatomoScriptElement } from './tracker/script-factory';
MatomoTracker,
provideMatomo,
ɵMATOMO_ROUTER_ENABLED as MATOMO_ROUTER_ENABLED,
} from 'ngx-matomo-client/core';

describe('providers', () => {
async function setUp(providers: TestModuleMetadata['providers']): Promise<void> {
@@ -34,59 +25,6 @@ describe('providers', () => {
await TestBed.inject(ApplicationInitStatus).donePromise;
}

it('should provide basic Matomo providers with static configuration', async () => {
const fakeInitializer = jasmine.createSpyObj<MatomoInitializerService>(['initialize']);
const config: MatomoConfiguration = { trackerUrl: 'my-tracker', siteId: 42 };

await setUp([
{
provide: MatomoInitializerService,
useValue: fakeInitializer,
},
provideMatomo(config),
]);

expect(TestBed.inject(MatomoTracker)).toEqual(jasmine.any(MatomoTracker));
expect(TestBed.inject(MATOMO_CONFIGURATION)).toEqual(config);
expect(fakeInitializer.initialize).toHaveBeenCalledTimes(1);
});

it('should provide basic Matomo providers with configuration factory', async () => {
const fakeInitializer = jasmine.createSpyObj<MatomoInitializerService>(['initialize']);
const trackerUrl = 'my-tracker';
const config: MatomoConfiguration = { trackerUrl, siteId: 42 };
const trackerUrlToken = new InjectionToken<string>('trackerUrl');

await setUp([
{
provide: MatomoInitializerService,
useValue: fakeInitializer,
},
{
provide: trackerUrlToken,
useValue: trackerUrl,
},
provideMatomo(() => ({ trackerUrl: TestBed.inject(trackerUrlToken), siteId: 42 })),
]);

expect(TestBed.inject(MatomoTracker)).toEqual(jasmine.any(MatomoTracker));
expect(TestBed.inject(MATOMO_CONFIGURATION)).toEqual(config);
expect(fakeInitializer.initialize).toHaveBeenCalledTimes(1);
});

it('should provide basic Matomo providers with custom script factory', async () => {
const scriptFactory = jasmine
.createSpy('scriptFactory')
.and.callFake(createDefaultMatomoScriptElement);

await setUp([
provideMatomo({ trackerUrl: 'my-tracker', siteId: 42 }, withScriptFactory(scriptFactory)),
]);

expect(TestBed.inject(MatomoTracker)).toEqual(jasmine.any(MatomoTracker));
expect(scriptFactory).toHaveBeenCalledTimes(1);
});

it('should provide basic Matomo providers with router feature', async () => {
await setUp([
provideMatomo({ trackerUrl: 'my-tracker', siteId: 42 }, withRouter({ delay: 42 })),
57 changes: 57 additions & 0 deletions projects/ngx-matomo-client/router/providers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {
ɵcreateMatomoFeature as createMatomoFeature,
ɵMATOMO_ROUTER_ENABLED as MATOMO_ROUTER_ENABLED,
ɵMatomoFeature as MatomoFeature,
ɵMatomoFeatureKind as MatomoFeatureKind,
} from 'ngx-matomo-client/core';
import { ENVIRONMENT_INITIALIZER, inject, Provider, Type } from '@angular/core';
import { MATOMO_ROUTER_CONFIGURATION, MatomoRouterConfiguration } from './configuration';
import { MatomoRouter } from './matomo-router.service';
import {
MATOMO_ROUTE_DATA_KEY,
MatomoRouteDataInterceptor,
} from './interceptors/route-data-interceptor';
import { MatomoRouterInterceptor, provideInterceptor, provideInterceptors } from './interceptor';

/** Enable automatic page views tracking */
export function withRouter(config?: MatomoRouterConfiguration): MatomoFeature {
const providers = [
{ provide: MATOMO_ROUTER_ENABLED, useValue: true },
{ provide: MATOMO_ROUTER_CONFIGURATION, useValue: config },
{
provide: ENVIRONMENT_INITIALIZER,
multi: true,
useValue() {
inject(MatomoRouter).initialize();
},
},
];

return createMatomoFeature(MatomoFeatureKind.Router, providers);
}

/** Add some matomo router interceptors */
export function withRouterInterceptors(
interceptors: Type<MatomoRouterInterceptor>[]
): MatomoFeature {
return createMatomoFeature(
MatomoFeatureKind.RouterInterceptors,
provideInterceptors(interceptors)
);
}

/**
* Enable retrieval of tracking information from route data
*
* @see MatomoRouteData
* @param key A custom key to get lookup route data - default is 'matomo'
*/
export function withRouteData(key?: string): MatomoFeature {
const providers: Provider[] = [provideInterceptor(MatomoRouteDataInterceptor)];

if (key) {
providers.push({ provide: MATOMO_ROUTE_DATA_KEY, useValue: key });
}

return createMatomoFeature(MatomoFeatureKind.BuiltInRouteDataInterceptor, providers);
}
26 changes: 26 additions & 0 deletions projects/ngx-matomo-client/router/public-api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Public API Surface of tracker
*/

export { withRouter, withRouterInterceptors, withRouteData } from './providers';
export { NgxMatomoRouterModule } from './ngx-matomo-router.module';
export {
MatomoRouterConfiguration,
MATOMO_ROUTER_CONFIGURATION,
ExclusionConfig,
MatomoRouterConfigurationWithInterceptors,
} from './configuration';
export { PageTitleProvider, MATOMO_PAGE_TITLE_PROVIDER } from './page-title-providers';
export { PageUrlProvider, MATOMO_PAGE_URL_PROVIDER } from './page-url-provider';
export {
MatomoRouterInterceptor,
MATOMO_ROUTER_INTERCEPTORS,
provideInterceptor,
provideInterceptors,
} from './interceptor';
export { MatomoRouteInterceptorBase } from './interceptors/route-interceptor-base';
export {
MatomoRouteData,
MatomoRouteDataInterceptor,
MATOMO_ROUTE_DATA_KEY,
} from './interceptors/route-data-interceptor';
62 changes: 40 additions & 22 deletions projects/ngx-matomo-client/schematics/ng-add/index.ts
Original file line number Diff line number Diff line change
@@ -28,26 +28,17 @@ import {
import { version } from '../version';
import { Schema as Options } from './schema';

/***********************************************************************************/
/* Important note: this schematic depends on non-public API of @schematics/angular */

/***********************************************************************************/

function checkRequiredRouterDependency(host: Tree, context: SchematicContext) {
const ngRouter = getPackageJsonDependency(host, '@angular/router');
function hasAngularRouterDependency(host: Tree): boolean {
return getPackageJsonDependency(host, '@angular/router') != null;
}

if (!ngRouter) {
function checkRequiredRouterDependency(host: Tree) {
if (!hasAngularRouterDependency(host)) {
throw new SchematicsException(
`You chose to automatically track page view, but this requires @angular/router as a dependency.\n` +
`You can run "ng add @angular/router" to add it to your application.`
);
}

if (ngRouter.type !== NodeDependencyType.Default) {
context.logger.warn(
`You chose to automatically track page view, but @angular/router is listed as "${ngRouter.type}" dependency.`
);
}
}

function addPackageJsonDependencies(options: Options) {
@@ -64,7 +55,7 @@ function addPackageJsonDependencies(options: Options) {
}

if (options.router) {
checkRequiredRouterDependency(host, context);
checkRequiredRouterDependency(host);
}

context.addTask(new NodePackageInstallTask());
@@ -118,7 +109,11 @@ function isLegacyImportPath(importPath: string): boolean {
}

function isRelevantImportPath(importPath: string): boolean {
return importPath === 'ngx-matomo-client' || isLegacyImportPath(importPath);
return (
importPath === 'ngx-matomo-client' ||
importPath.startsWith('ngx-matomo-client/') ||
isLegacyImportPath(importPath)
);
}

function findRelevantImports(
@@ -157,6 +152,20 @@ function hasLegacyModuleDeclaration(source: ts.SourceFile): boolean {
.some(el => (el as ts.Identifier).getText().startsWith('NgxMatomo'));
}

function getImportEntryPoints(
host: Tree,
options: Options
): {
core: string;
router: string;
} {
const useSecondaryEntryPoint = !hasAngularRouterDependency(host) && !options.router;
const core = useSecondaryEntryPoint ? 'ngx-matomo-client/core' : 'ngx-matomo-client';
const router = useSecondaryEntryPoint ? 'ngx-matomo-client/router' : 'ngx-matomo-client';

return { core, router };
}

function addImportsToNgModule(options: Options, context: SchematicContext): Rule {
return (host: Tree) => {
const modulePath = options.module;
@@ -168,6 +177,7 @@ function addImportsToNgModule(options: Options, context: SchematicContext): Rule
const changes: Change[] = [];
const source = readIntoSourceFile(host, modulePath);
const trackerConfig = buildTrackerConfig(options, context, modulePath);
const entryPoints = getImportEntryPoints(host, options);

// If some Matomo imports are already present, use the legacy setup using
// NgModule.
@@ -232,7 +242,7 @@ function addImportsToNgModule(options: Options, context: SchematicContext): Rule
);

if (!mainModuleImported) {
changes.push(insertImport(source, modulePath, mainModuleIdentifier, 'ngx-matomo-client'));
changes.push(insertImport(source, modulePath, mainModuleIdentifier, entryPoints.core));
}

changes.push(
@@ -247,7 +257,7 @@ function addImportsToNgModule(options: Options, context: SchematicContext): Rule
if (options.router) {
if (!routerModuleImported) {
changes.push(
insertImport(source, modulePath, routerModuleIdentifier, 'ngx-matomo-client')
insertImport(source, modulePath, routerModuleIdentifier, entryPoints.router)
);
}

@@ -258,10 +268,10 @@ function addImportsToNgModule(options: Options, context: SchematicContext): Rule
} else {
const provideMatomoArgs = [trackerConfig];

changes.push(insertImport(source, modulePath, 'provideMatomo', 'ngx-matomo-client'));
changes.push(insertImport(source, modulePath, 'provideMatomo', entryPoints.core));

if (options.router) {
changes.push(insertImport(source, modulePath, 'withRouter', 'ngx-matomo-client'));
changes.push(insertImport(source, modulePath, 'withRouter', entryPoints.router));

provideMatomoArgs.push(`withRouter()`);
}
@@ -297,6 +307,7 @@ function migrateAllLegacyImports(options: Options, context: SchematicContext): R

if (!options.path || path.startsWith(options.path)) {
const file = readIntoSourceFile(host, path);
const entryPoints = getImportEntryPoints(host, options);
const changes: Change[] = [];

file.forEachChild(node => {
@@ -307,9 +318,16 @@ function migrateAllLegacyImports(options: Options, context: SchematicContext): R
const text = moduleSpecifier.text;
const pos = moduleSpecifier.pos;

if (text?.startsWith('@ngx-matomo/')) {
if (text === '@ngx-matomo/tracker') {
// Be sure to keep any original spacings (contained in getFullText() only)
const newFullText = fullText.replace(text, entryPoints.core);

changes.push(new ReplaceChange(path, pos, fullText, newFullText));
}

if (text === '@ngx-matomo/router') {
// Be sure to keep any original spacings (contained in getFullText() only)
const newFullText = fullText.replace(text, 'ngx-matomo-client');
const newFullText = fullText.replace(text, entryPoints.router);

changes.push(new ReplaceChange(path, pos, fullText, newFullText));
}
1 change: 1 addition & 0 deletions projects/ngx-matomo-client/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './public-api';
63 changes: 2 additions & 61 deletions projects/ngx-matomo-client/src/public-api.ts
Original file line number Diff line number Diff line change
@@ -2,64 +2,5 @@
* Public API Surface of tracker
*/

export {
NgxMatomoModule,
NgxMatomoTrackerModule,
MATOMO_DIRECTIVES,
} from './lib/ngx-matomo.module';
export {
provideMatomo,
withScriptFactory,
withRouter,
withRouterInterceptors,
withRouteData,
MatomoFeatureKind,
MatomoFeature,
} from './lib/ngx-matomo-providers';
export {
MatomoTracker,
MatomoECommerceItem,
MatomoECommerceView,
MatomoECommerceItemView,
MatomoECommerceCategoryView,
PagePerformanceTimings,
} from './lib/tracker/matomo-tracker.service';
export { MatomoInitializerService } from './lib/tracker/matomo-initializer.service';
export {
MatomoConfiguration,
MATOMO_CONFIGURATION,
AutoMatomoConfiguration,
MatomoInitializationMode,
MatomoConsentMode,
InternalMatomoConfiguration,
INTERNAL_MATOMO_CONFIGURATION,
} from './lib/tracker/configuration';
export {
MATOMO_SCRIPT_FACTORY,
MatomoScriptFactory,
createDefaultMatomoScriptElement,
} from './lib/tracker/script-factory';
export { MatomoTrackerDirective } from './lib/directives/matomo-tracker.directive';
export { MatomoTrackClickDirective } from './lib/directives/matomo-track-click.directive';
export { MatomoOptOutFormComponent } from './lib/directives/matomo-opt-out-form.component';
export { NgxMatomoRouterModule } from './lib/ngx-matomo-router.module';
export {
MatomoRouterConfiguration,
MATOMO_ROUTER_CONFIGURATION,
ExclusionConfig,
MatomoRouterConfigurationWithInterceptors,
} from './lib/router/configuration';
export { PageTitleProvider, MATOMO_PAGE_TITLE_PROVIDER } from './lib/router/page-title-providers';
export { PageUrlProvider, MATOMO_PAGE_URL_PROVIDER } from './lib/router/page-url-provider';
export {
MatomoRouterInterceptor,
MATOMO_ROUTER_INTERCEPTORS,
provideInterceptor,
provideInterceptors,
} from './lib/router/interceptor';
export { MatomoRouteInterceptorBase } from './lib/router/interceptors/route-interceptor-base';
export {
MatomoRouteData,
MatomoRouteDataInterceptor,
MATOMO_ROUTE_DATA_KEY,
} from './lib/router/interceptors/route-data-interceptor';
export * from 'ngx-matomo-client/core';
export * from 'ngx-matomo-client/router';
File renamed without changes.
3 changes: 1 addition & 2 deletions projects/ngx-matomo-client/tsconfig.lib.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
"extends": "../../tsconfig.json",
"compilerOptions": {
@@ -14,5 +13,5 @@
"strictMetadataEmit": true,
"enableResourceInlining": true
},
"exclude": ["src/test.ts", "**/*.spec.ts"]
"exclude": ["test.ts", "**/*.spec.ts"]
}
2 changes: 1 addition & 1 deletion projects/ngx-matomo-client/tsconfig.spec.json
Original file line number Diff line number Diff line change
@@ -5,6 +5,6 @@
"outDir": "../../out-tsc/spec",
"types": ["jasmine"]
},
"files": ["src/test.ts"],
"files": ["test.ts"],
"include": ["**/*.spec.ts", "**/*.d.ts"]
}
2 changes: 1 addition & 1 deletion scripts/detect-missing-api.mjs
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import * as cheerio from 'cheerio';
import * as fs from 'fs/promises';

const DOCUMENTATION_URL = 'https://developer.matomo.org/api-reference/tracking-javascript';
const TRACKER_FILE_PATH = 'projects/ngx-matomo-client/src/lib/tracker/matomo-tracker.service.ts';
const TRACKER_FILE_PATH = 'projects/ngx-matomo-client/core/tracker/matomo-tracker.service.ts';
const GLOBAL_METHOD_PREFIX = 'Matomo.';
const ACCEPTED_METHOD_PREFIXES = ['matomoTracker.', 'tracker.'];
const EXCLUSIONS = /\//;
3 changes: 2 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -18,7 +18,8 @@
"module": "es2020",
"lib": ["es2018", "dom"],
"paths": {
"ngx-matomo-client": ["dist/ngx-matomo-client"]
"ngx-matomo-client": ["dist/ngx-matomo-client"],
"ngx-matomo-client/*": ["dist/ngx-matomo-client/*"]
},
"useDefineForClassFields": false
},

0 comments on commit 89f9344

Please sign in to comment.