ngx-route-manager
Version:
A route management library for Angular
204 lines (192 loc) • 6.38 kB
JavaScript
import * as i0 from '@angular/core';
import { signal, InjectionToken, APP_INITIALIZER, NgModule, computed } from '@angular/core';
import { NavigationEnd, Router, ActivatedRoute } from '@angular/router';
import { filter, of, map } from 'rxjs';
const internalSignalRoute = signal(undefined);
// Factory function to initialize the service
function listenForRouteChange(router, route) {
return () => {
internalSignalRoute.set(route);
const subscription = router.events.pipe(filter(event => event instanceof NavigationEnd)).subscribe(() => {
// Traverse to the most deeply activated route
let route = router.routerState.root;
while (route.firstChild) {
route = route.firstChild;
}
internalSignalRoute.set(route);
});
return () => subscription.unsubscribe();
};
}
const NGX_ROUTE_MANAGER_CONFIG = new InjectionToken('NGX_ROUTE_MANAGER_CONFIG');
class NgxRouteManagerModule {
static forRoot(config) {
return {
ngModule: NgxRouteManagerModule,
providers: [
{
provide: NGX_ROUTE_MANAGER_CONFIG,
useValue: config
},
{
provide: APP_INITIALIZER,
useFactory: listenForRouteChange,
deps: [Router, ActivatedRoute],
multi: true
}
]
};
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NgxRouteManagerModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule });
static ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.5", ngImport: i0, type: NgxRouteManagerModule });
static ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NgxRouteManagerModule });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.5", ngImport: i0, type: NgxRouteManagerModule, decorators: [{
type: NgModule,
args: [{}]
}] });
// type ExtractParams<T extends string> =
// T extends `${infer _Start}:${infer Param}/${infer Rest}` ?
// Param | ExtractParams<Rest> :
// T extends `${infer _Start}:${infer Param}` ?
// Param :
// string;
function createUrlFunction(template) {
return ((args) => {
if (args === undefined && template.includes(':')) {
throw new Error('Arguments are required for this template');
}
if (args !== undefined && !template.includes(':')) {
throw new Error('This template does not accept any arguments');
}
return template.replace(/:([a-zA-Z]+)/g, (_, key) => {
return args?.[key] ?? '';
});
});
}
class NgxParam {
/**
* Name of the param
*/
_name = '';
get name() {
return this._name;
}
/**
* Returns the current snapshoot of the value in the url route
*/
snapshotValue = computed(() => {
if (!internalSignalRoute()) {
return '';
}
else {
return internalSignalRoute()?.snapshot.paramMap.get(this.name) || '';
}
});
/**
* Listens for change on param in the route
*/
listenForValue = computed(() => {
if (!internalSignalRoute()) {
console.log(internalSignalRoute());
return of('');
}
else {
return internalSignalRoute()?.paramMap
.pipe(filter(paramMap => paramMap.has(this.name)), map(paramMap => paramMap.get(this.name) || ''));
}
});
constructor(name) {
this._name = name;
}
}
function urlToNgxParam(route) {
const segments = route.split('/');
const params = {};
segments.forEach(segment => {
if (segment.startsWith(':')) {
const param = segment.slice(1);
if (!/^[A-Za-z]+$/.test(param)) {
throw new Error(`${param} must contain only alphabets in ${route}`);
}
params[param] = new NgxParam(param);
}
});
return params;
}
class NgxRoute {
/**
* The url path
*/
path = '';
/**
* Function to generate the url, requiring the right params
*/
fn = {};
/**
* Stores all the params as
*/
_params = {};
/**
* Stores all the segments as
*/
_segments = {};
constructor(path, fn, params, segments) {
this.path = path;
this.fn = fn;
this._params = params;
this._segments = segments;
}
/**
* All params store as an object
*/
get params() {
return this._params;
}
/**
* All segments store as an object
*/
get segments() {
return this._segments;
}
}
/**
* Extracts static segments from a URL pattern and returns them as a typed object
* Types are automatically inferred from the URL pattern
* @param url - The URL pattern to parse
* @returns Object with extracted segments with automatic type inference
*/
function urlToSegments(url) {
// Remove leading and trailing slashes
const cleanUrl = url.replace(/^\/+|\/+$/g, '');
// Split the URL into segments
const segments = cleanUrl.split('/');
// Initialize result object
const result = {};
// Process each segment
segments.forEach(segment => {
// Skip dynamic segments (those starting with ':')
if (segment.startsWith(':') || segment.trim().length == 0) {
return;
}
if (!/^[a-zA-Z][a-zA-Z0-9-_]*$/.test(segment)) {
throw new Error(`Segment '${segment}' must start with a letter and contain only letters, numbers, hyphens, or underscores in ${url}`);
}
// Add valid segments to result object
result[segment] = segment;
});
return result;
}
function generateNgxRoute(urlPattern) {
const pattern = urlPattern ? urlPattern : '';
const ngxRoute = new NgxRoute(pattern, createUrlFunction(pattern), urlToNgxParam(pattern), urlToSegments(pattern));
return ngxRoute;
}
/*
* Public API Surface of ngx-route-manager
*/
/**
* Generated bundle index. Do not edit.
*/
export { NgxRouteManagerModule, generateNgxRoute };
//# sourceMappingURL=ngx-route-manager.mjs.map