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