Compare commits
	
		
			2 Commits
		
	
	
		
			d25a844fac
			...
			f7d292932f
		
	
	| Author | SHA1 | Date | 
|---|---|---|
| 
							
							
								
									
								
								 | 
						f7d292932f | |
| 
							
							
								
									
								
								 | 
						93096b839a | 
| 
						 | 
					@ -1,6 +1,6 @@
 | 
				
			||||||
import {customAlphabet} from 'nanoid';
 | 
					import {customAlphabet} from 'nanoid';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const matcherTypes = ['hostname'] as const;
 | 
					export const matcherTypes = ['hostname', 'regex'] as const;
 | 
				
			||||||
export const redirectTypes = ['hostname', 'simple'] as const;
 | 
					export const redirectTypes = ['hostname', 'simple'] as const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type MatcherType = typeof matcherTypes[number];
 | 
					export type MatcherType = typeof matcherTypes[number];
 | 
				
			||||||
| 
						 | 
					@ -14,16 +14,14 @@ export function narrowRedirectType(value: string): value is RedirectType {
 | 
				
			||||||
  return redirectTypes.includes(value as RedirectType);
 | 
					  return redirectTypes.includes(value as RedirectType);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Matcher = {
 | 
					 | 
				
			||||||
  matcherType: MatcherType;
 | 
					 | 
				
			||||||
  toMatch: string;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export type RedirectParameters = {
 | 
					export type RedirectParameters = {
 | 
				
			||||||
 | 
					  matcherType: MatcherType;
 | 
				
			||||||
 | 
					  matcherValue: string;
 | 
				
			||||||
  redirectType: RedirectType;
 | 
					  redirectType: RedirectType;
 | 
				
			||||||
 | 
					  redirectValue: string;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export abstract class Redirect<P extends RedirectParameters> {
 | 
					export abstract class Redirect {
 | 
				
			||||||
  public static generateId(): string {
 | 
					  public static generateId(): string {
 | 
				
			||||||
    const alphabet = 'abcdefghijklmnopqrstuvwxyz';
 | 
					    const alphabet = 'abcdefghijklmnopqrstuvwxyz';
 | 
				
			||||||
    const nanoid = customAlphabet(`${alphabet}${alphabet.toUpperCase()}`, 20);
 | 
					    const nanoid = customAlphabet(`${alphabet}${alphabet.toUpperCase()}`, 20);
 | 
				
			||||||
| 
						 | 
					@ -32,7 +30,7 @@ export abstract class Redirect<P extends RedirectParameters> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public id: string;
 | 
					  public id: string;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  constructor(public parameters: P & Matcher, id?: string) {
 | 
					  constructor(public parameters: RedirectParameters, id?: string) {
 | 
				
			||||||
    this.id = id ?? Redirect.generateId();
 | 
					    this.id = id ?? Redirect.generateId();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -41,15 +39,16 @@ export abstract class Redirect<P extends RedirectParameters> {
 | 
				
			||||||
      const hostname = url.hostname.startsWith('www.')
 | 
					      const hostname = url.hostname.startsWith('www.')
 | 
				
			||||||
        ? url.hostname.slice(4)
 | 
					        ? url.hostname.slice(4)
 | 
				
			||||||
        : url.hostname;
 | 
					        : url.hostname;
 | 
				
			||||||
      return hostname === this.parameters.toMatch;
 | 
					      return hostname === this.parameters.matcherValue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (this.parameters.matcherType === 'regex') {
 | 
				
			||||||
 | 
					      const regex = new RegExp(this.parameters.matcherValue, 'gi');
 | 
				
			||||||
 | 
					      return regex.test(url.href);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public abstract redirect(url: URL | string): URL;
 | 
					  public abstract redirect(url: URL | string): URL;
 | 
				
			||||||
 | 
					 | 
				
			||||||
  public abstract get redirectValue(): string;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public abstract set redirectValue(value: string);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					import {RedirectParameters} from './base.js';
 | 
				
			||||||
import {HostnameRedirect} from './hostname.js';
 | 
					import {HostnameRedirect} from './hostname.js';
 | 
				
			||||||
import {SimpleRedirect} from './simple.js';
 | 
					import {SimpleRedirect} from './simple.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,8 +8,8 @@ export * from './simple.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type Redirects = HostnameRedirect | SimpleRedirect;
 | 
					export type Redirects = HostnameRedirect | SimpleRedirect;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function parseRedirect<P extends Redirects['parameters']>(
 | 
					export function parseRedirect(
 | 
				
			||||||
  parameters: P,
 | 
					  parameters: RedirectParameters,
 | 
				
			||||||
  id: string,
 | 
					  id: string,
 | 
				
			||||||
): Redirects | undefined {
 | 
					): Redirects | undefined {
 | 
				
			||||||
  const redirectType = parameters?.redirectType;
 | 
					  const redirectType = parameters?.redirectType;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,22 +1,9 @@
 | 
				
			||||||
import {Redirect} from './base.js';
 | 
					import {Redirect} from './base.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type HostnameParameters = {
 | 
					export class HostnameRedirect extends Redirect {
 | 
				
			||||||
  hostname: string;
 | 
					 | 
				
			||||||
  redirectType: 'hostname';
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class HostnameRedirect extends Redirect<HostnameParameters> {
 | 
					 | 
				
			||||||
  public redirect(url: URL | string): URL {
 | 
					  public redirect(url: URL | string): URL {
 | 
				
			||||||
    const redirected = new URL(url);
 | 
					    const redirected = new URL(url);
 | 
				
			||||||
    redirected.hostname = this.parameters.hostname;
 | 
					    redirected.hostname = this.parameters.redirectValue;
 | 
				
			||||||
    return redirected;
 | 
					    return redirected;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
  public get redirectValue(): string {
 | 
					 | 
				
			||||||
    return this.parameters.hostname;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public set redirectValue(value: string) {
 | 
					 | 
				
			||||||
    this.parameters.hostname = value;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,20 +1,7 @@
 | 
				
			||||||
import {Redirect} from './base.js';
 | 
					import {Redirect} from './base.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export type SimpleParameters = {
 | 
					export class SimpleRedirect extends Redirect {
 | 
				
			||||||
  target: string;
 | 
					 | 
				
			||||||
  redirectType: 'simple';
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
export class SimpleRedirect extends Redirect<SimpleParameters> {
 | 
					 | 
				
			||||||
  public redirect(): URL {
 | 
					  public redirect(): URL {
 | 
				
			||||||
    return new URL(this.parameters.target);
 | 
					    return new URL(this.parameters.redirectValue);
 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public get redirectValue(): string {
 | 
					 | 
				
			||||||
    return this.parameters.target;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  public set redirectValue(value: string) {
 | 
					 | 
				
			||||||
    this.parameters.target = value;
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -15,26 +15,26 @@ import {
 | 
				
			||||||
  SimpleRedirect,
 | 
					  SimpleRedirect,
 | 
				
			||||||
} from '../source/redirect/exports.js';
 | 
					} from '../source/redirect/exports.js';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const hostnameParameters: HostnameRedirect['parameters'] = {
 | 
					const hostnameParameters: RedirectParameters = {
 | 
				
			||||||
  hostname: 'example.org',
 | 
					 | 
				
			||||||
  matcherType: 'hostname',
 | 
					  matcherType: 'hostname',
 | 
				
			||||||
  toMatch: 'example.com',
 | 
					  matcherValue: 'example.com',
 | 
				
			||||||
  redirectType: 'hostname',
 | 
					  redirectType: 'hostname',
 | 
				
			||||||
 | 
					  redirectValue: 'example.org',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const simpleParameters: SimpleRedirect['parameters'] = {
 | 
					const simpleParameters: RedirectParameters = {
 | 
				
			||||||
  matcherType: 'hostname',
 | 
					  matcherType: 'hostname',
 | 
				
			||||||
  target: 'https://example.org/simple',
 | 
					  matcherValue: 'example.com',
 | 
				
			||||||
  toMatch: 'example.com',
 | 
					 | 
				
			||||||
  redirectType: 'simple',
 | 
					  redirectType: 'simple',
 | 
				
			||||||
 | 
					  redirectValue: 'https://example.org/simple',
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
test('parseRedirect', (t) => {
 | 
					test('parseRedirect', (t) => {
 | 
				
			||||||
  const samples: Array<Redirects['parameters']> = [
 | 
					  const samples: RedirectParameters[] = [
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
      test: 'Invalid parameters',
 | 
					      test: 'Invalid parameters',
 | 
				
			||||||
    } as unknown as Redirects['parameters'],
 | 
					    } as unknown as RedirectParameters,
 | 
				
			||||||
    undefined as unknown as Redirects['parameters'],
 | 
					    undefined as unknown as RedirectParameters,
 | 
				
			||||||
    hostnameParameters,
 | 
					    hostnameParameters,
 | 
				
			||||||
    simpleParameters,
 | 
					    simpleParameters,
 | 
				
			||||||
  ];
 | 
					  ];
 | 
				
			||||||
| 
						 | 
					@ -56,7 +56,7 @@ test('Redirect.redirect', (t) => {
 | 
				
			||||||
  const hostnameRedirect = new HostnameRedirect(hostnameParameters);
 | 
					  const hostnameRedirect = new HostnameRedirect(hostnameParameters);
 | 
				
			||||||
  const simpleRedirect = new SimpleRedirect(simpleParameters);
 | 
					  const simpleRedirect = new SimpleRedirect(simpleParameters);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const samples: Array<[string, Redirect<RedirectParameters>]> = [
 | 
					  const samples: Array<[string, Redirect]> = [
 | 
				
			||||||
    ['https://example.com', hostnameRedirect],
 | 
					    ['https://example.com', hostnameRedirect],
 | 
				
			||||||
    ['https://example.com/path#hash?query=test', hostnameRedirect],
 | 
					    ['https://example.com/path#hash?query=test', hostnameRedirect],
 | 
				
			||||||
    ['https://example.com', simpleRedirect],
 | 
					    ['https://example.com', simpleRedirect],
 | 
				
			||||||
| 
						 | 
					@ -106,17 +106,3 @@ test('Narrow match & redirect types', (t) => {
 | 
				
			||||||
  t.true(matcherTypes.every((value) => narrowMatcherType(value)));
 | 
					  t.true(matcherTypes.every((value) => narrowMatcherType(value)));
 | 
				
			||||||
  t.true(redirectTypes.every((value) => narrowRedirectType(value)));
 | 
					  t.true(redirectTypes.every((value) => narrowRedirectType(value)));
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					 | 
				
			||||||
test('Redirect getters & setters', (t) => {
 | 
					 | 
				
			||||||
  const samples: Array<[Redirects, string]> = [
 | 
					 | 
				
			||||||
    [new HostnameRedirect(hostnameParameters), hostnameParameters.hostname],
 | 
					 | 
				
			||||||
    [new SimpleRedirect(simpleParameters), simpleParameters.target],
 | 
					 | 
				
			||||||
  ];
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  for (const [redirect, value] of samples) {
 | 
					 | 
				
			||||||
    t.is(redirect.redirectValue, value);
 | 
					 | 
				
			||||||
    const newValue = `${value} test`;
 | 
					 | 
				
			||||||
    redirect.redirectValue = newValue;
 | 
					 | 
				
			||||||
    t.is(redirect.redirectValue, newValue);
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,10 +11,10 @@ Generated by [AVA](https://avajs.dev).
 | 
				
			||||||
    HostnameRedirect {
 | 
					    HostnameRedirect {
 | 
				
			||||||
      id: 'id',
 | 
					      id: 'id',
 | 
				
			||||||
      parameters: {
 | 
					      parameters: {
 | 
				
			||||||
        hostname: 'example.org',
 | 
					 | 
				
			||||||
        matcherType: 'hostname',
 | 
					        matcherType: 'hostname',
 | 
				
			||||||
 | 
					        matcherValue: 'example.com',
 | 
				
			||||||
        redirectType: 'hostname',
 | 
					        redirectType: 'hostname',
 | 
				
			||||||
        toMatch: 'example.com',
 | 
					        redirectValue: 'example.org',
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,9 +24,9 @@ Generated by [AVA](https://avajs.dev).
 | 
				
			||||||
      id: 'id',
 | 
					      id: 'id',
 | 
				
			||||||
      parameters: {
 | 
					      parameters: {
 | 
				
			||||||
        matcherType: 'hostname',
 | 
					        matcherType: 'hostname',
 | 
				
			||||||
 | 
					        matcherValue: 'example.com',
 | 
				
			||||||
        redirectType: 'simple',
 | 
					        redirectType: 'simple',
 | 
				
			||||||
        target: 'https://example.org/simple',
 | 
					        redirectValue: 'https://example.org/simple',
 | 
				
			||||||
        toMatch: 'example.com',
 | 
					 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											Binary file not shown.
										
									
								
							
		Reference in New Issue