literium-router
Advanced tools
Comparing version 0.1.1 to 0.2.0
@@ -1,63 +0,68 @@ | ||
export interface PathArg<TypeMap> { | ||
[name: string]: keyof TypeMap; | ||
import { Option } from 'literium-base'; | ||
export interface Route<Args> { | ||
m(s: string): [Args, string] | void; | ||
f(v: Args): string | void; | ||
} | ||
export declare type ArgMap<TypeMap, Arg extends PathArg<TypeMap>> = { | ||
[Name in keyof Arg]: TypeMap[Arg[Name]]; | ||
}; | ||
export interface TypeImpl<Type> { | ||
parse(path: string): [Type, string] | void; | ||
build(arg: Type): string | void; | ||
export interface ArgType<Type> { | ||
r: RegExp; | ||
p(s: string | void): Option<Type>; | ||
b(v: Type): string | void; | ||
} | ||
export declare type TypeApi<TypeMap> = { | ||
[Tag in keyof TypeMap]: TypeImpl<TypeMap[Tag]>; | ||
}; | ||
export interface Route<Args> { | ||
parse(path: string): [Args, string] | void; | ||
build(args: Args): string | void; | ||
} | ||
export declare type Routes<State> = { | ||
[Id in keyof State]: Route<State[Id]>; | ||
}; | ||
export declare function type_and<TypeMap1, TypeMap2>(api1: TypeApi<TypeMap1>, api2: TypeApi<TypeMap2>): TypeApi<TypeMap1 & TypeMap2>; | ||
export declare function route_match<Args>(route: Route<Args>, path: string): Args | void; | ||
export declare function route_build<Args, ActualArgs extends Args>(route: Route<Args>, args: ActualArgs & Args): string; | ||
export declare function route_str(path: string): Route<{}>; | ||
export declare function route_def<Arg>(arg: Arg): Route<Arg>; | ||
export declare function route_arg<TypeMap, Arg extends PathArg<TypeMap>>(arg: Arg, type_api: TypeApi<TypeMap>): Route<ArgMap<TypeMap, Arg>>; | ||
export declare function route_or<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 | Args2>; | ||
export declare function route_or<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 | Args2 | Args3>; | ||
export declare function route_or<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 | Args2 | Args3 | Args4>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 | Args2 | Args3 | Args4 | Args5>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function route_and<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 & Args2>; | ||
export declare function route_and<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 & Args2 & Args3>; | ||
export declare function route_and<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 & Args2 & Args3 & Args4>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 & Args2 & Args3 & Args4 & Args5>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15, Args16>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>, r16: Route<Args16>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15 & Args16>; | ||
export declare function router_match<State>(routes: Routes<State>, path: string): Partial<State> | void; | ||
export declare function router_build<State>(routes: Routes<State>, state: Partial<State>): string | void; | ||
export interface BaseTypes { | ||
str: string; | ||
num: number; | ||
} | ||
export declare const baseTypes: TypeApi<BaseTypes>; | ||
export interface NumTypes { | ||
nat: number; | ||
int: number; | ||
} | ||
export declare const numTypes: TypeApi<NumTypes>; | ||
export declare function match<Args>({m}: Route<Args>, path: string): Args | void; | ||
export declare function build<Args, ActualArgs extends Args>({f}: Route<Args>, args: ActualArgs & Args): string; | ||
export declare function dir(path: string): Route<{}>; | ||
export declare function ins<Arg>(arg: Arg): Route<Arg>; | ||
export declare type ArgMap<TypeMap> = { | ||
[Tag in keyof TypeMap]: ArgType<TypeMap[Tag]>; | ||
}; | ||
export declare function arg<TypeMap>(arg: ArgMap<TypeMap>): Route<TypeMap>; | ||
export declare type QueryArgs = Record<string, string | void>; | ||
export declare function query_parse(str: string): QueryArgs; | ||
export declare function query_build(args: QueryArgs): string; | ||
export declare function query<TypeMap>(arg: ArgMap<TypeMap>, qmark?: boolean): Route<TypeMap>; | ||
export declare function alt<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 | Args2>; | ||
export declare function alt<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 | Args2 | Args3>; | ||
export declare function alt<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 | Args2 | Args3 | Args4>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 | Args2 | Args3 | Args4 | Args5>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function alt<Type1, Type2>(t1: ArgType<Type1>, t2: ArgType<Type2>): ArgType<Type1 | Type2>; | ||
export declare function alt<Type1, Type2, Type3>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>): ArgType<Type1 | Type2 | Type3>; | ||
export declare function alt<Type1, Type2, Type3, Type4>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>): ArgType<Type1 | Type2 | Type3 | Type4>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>, t9: ArgType<Type9>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>, t9: ArgType<Type9>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9>; | ||
export declare function seq<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 & Args2>; | ||
export declare function seq<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 & Args2 & Args3>; | ||
export declare function seq<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 & Args2 & Args3 & Args4>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 & Args2 & Args3 & Args4 & Args5>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15, Args16>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>, r16: Route<Args16>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15 & Args16>; | ||
export declare function matchs<State>(routes: Routes<State>, path: string): Partial<State> | void; | ||
export declare function builds<State>(routes: Routes<State>, state: Partial<State>): string | void; | ||
export declare const str: ArgType<string>; | ||
export declare const num: ArgType<number>; | ||
export declare const und: ArgType<void>; | ||
export declare const int: ArgType<number>; | ||
export declare const nat: ArgType<number>; | ||
export declare function opt<Type>({r, p, b}: ArgType<Type>): ArgType<Type | void>; | ||
export declare function def<Type>({r, p, b}: ArgType<Type>, d: Type): ArgType<Type>; |
286
es/router.js
import * as tslib_1 from "tslib"; | ||
export function type_and(api1, api2) { | ||
return tslib_1.__assign({}, api1, api2); | ||
import { some, none } from 'literium-base'; | ||
var un_def = undefined; | ||
function is_def(v) { | ||
return v != un_def; | ||
} | ||
export function route_match(route, path) { | ||
var res = route.parse(path); | ||
if (!res || res[1] != '') | ||
export function match(_a, path) { | ||
var m = _a.m; | ||
var r = m(path); | ||
if (!r || r[1] != '') | ||
return; | ||
return res[0]; | ||
return r[0]; | ||
} | ||
@@ -14,20 +17,21 @@ // The trick with ActualArgs type parameter makes passed arguments to be the same as route expects. | ||
// Also it is important the arguments must be of the type 'ActualArgs & Args', because we cannot set type condition 'ActualArgs = Args'. | ||
export function route_build(route, args) { | ||
var path = route.build(args); | ||
if (path === undefined) | ||
export function build(_a, args) { | ||
var f = _a.f; | ||
var path = f(args); | ||
if (!is_def(path)) | ||
throw "Cannot build path"; | ||
return path; | ||
} | ||
export function route_str(path) { | ||
export function dir(path) { | ||
var ent = encodeURI(path); | ||
return { | ||
parse: function (path) { return path.substr(0, ent.length) == ent ? | ||
[{}, path.substr(ent.length)] : undefined; }, | ||
build: function () { return ent; } | ||
m: function (path) { return path.substr(0, ent.length) == ent ? | ||
[{}, path.substr(ent.length)] : un_def; }, | ||
f: function () { return ent; } | ||
}; | ||
} | ||
export function route_def(arg) { | ||
export function ins(arg) { | ||
return { | ||
parse: function (path) { return [arg, path]; }, | ||
build: function (args) { | ||
m: function (path) { return [arg, path]; }, | ||
f: function (args) { | ||
for (var key in arg) { | ||
@@ -41,10 +45,6 @@ if (!(key in args) || args[key] !== arg[key]) | ||
} | ||
export function route_arg(arg, type_api) { | ||
export function arg(arg) { | ||
var key; | ||
var tag; | ||
var api; | ||
for (var fld in arg) { | ||
key = fld; | ||
tag = arg[key]; | ||
api = type_api[tag]; | ||
break; | ||
@@ -54,41 +54,139 @@ } | ||
throw "No arg"; | ||
var _a = arg[key], r = _a.r, p = _a.p, b = _a.b; | ||
return { | ||
parse: function (path) { | ||
var res = api.parse(path); | ||
if (!res) | ||
m: function (path) { | ||
var res = r.exec(path); | ||
if (!is_def(res)) | ||
return; | ||
var val = res[0], rest = res[1]; | ||
return [(_a = {}, _a[key] = val, _a), rest]; | ||
var val = p(res[0]); | ||
if (!val.$) | ||
return; | ||
return [ | ||
(_a = {}, _a[key] = val._, _a), | ||
path.slice(res[0].length) | ||
]; | ||
var _a; | ||
}, | ||
build: function (args) { | ||
f: function (args) { | ||
if (!(key in args)) | ||
return; | ||
return api.build(args[key]); | ||
return b(args[key]); | ||
} | ||
}; | ||
} | ||
export function route_or() { | ||
var rs = []; | ||
export function query_parse(str) { | ||
var args = {}; | ||
if (str == '') | ||
return args; | ||
for (var _i = 0, _a = str.split(/&/); _i < _a.length; _i++) { | ||
var arg_1 = _a[_i]; | ||
var pair = arg_1.split(/=/); | ||
args[decodeURIComponent(pair[0])] = pair.length > 1 ? pair[1] : un_def; | ||
} | ||
return args; | ||
} | ||
export function query_build(args) { | ||
var strs = []; | ||
for (var name in args) { | ||
var value = args[name]; | ||
strs.push("" + encodeURIComponent(name) + (typeof value == 'string' ? "=" + value : '')); | ||
} | ||
return strs.join('&'); | ||
} | ||
export function query(arg, qmark) { | ||
if (qmark === void 0) { qmark = true; } | ||
var key; | ||
for (var fld in arg) { | ||
key = fld; | ||
break; | ||
} | ||
if (!key) | ||
throw "No args"; | ||
return { | ||
m: function (path) { | ||
if (qmark && path.charAt(0) != '?') | ||
return; | ||
var qargs = query_parse(qmark ? path.substring(1) : path); | ||
var args = {}; | ||
for (var key_1 in arg) { | ||
var _a = arg[key_1], r = _a.r, p = _a.p; | ||
var str_1 = qargs[key_1]; | ||
if (is_def(str_1)) { | ||
// check string value using regexp | ||
var res_ = r.exec(str_1); | ||
if (!is_def(res_) || | ||
res_[0].length != str_1.length) | ||
return; | ||
} | ||
var val = p(str_1); | ||
if (!val.$) | ||
return; | ||
if (is_def(val._)) | ||
args[key_1] = val._; | ||
} | ||
return [args, '']; | ||
}, | ||
f: function (args) { | ||
var qargs = {}; | ||
for (var key_2 in arg) { | ||
if (!(key_2 in args)) | ||
return; | ||
var b = arg[key_2].b; | ||
var val = b(args[key_2]); | ||
if (is_def(val)) | ||
qargs[key_2] = val; | ||
} | ||
var qstr = query_build(qargs); | ||
return "" + (qmark && qstr ? '?' : '') + qstr; | ||
} | ||
}; | ||
} | ||
export function alt() { | ||
var xs = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
rs[_i] = arguments[_i]; | ||
xs[_i] = arguments[_i]; | ||
} | ||
return { | ||
parse: function (path) { | ||
for (var i = 0; i < rs.length; i++) { | ||
var res = rs[i].parse(path); | ||
if (res !== undefined) | ||
return xs[0].m ? { | ||
m: function (path) { | ||
for (var i = 0; i < xs.length; i++) { | ||
var res = xs[i].m(path); | ||
if (is_def(res)) | ||
return res; | ||
} | ||
}, | ||
build: function (args) { | ||
for (var i = 0; i < rs.length; i++) { | ||
var path = rs[i].build(args); | ||
if (path !== undefined) | ||
f: function (args) { | ||
for (var i = 0; i < xs.length; i++) { | ||
var path = xs[i].f(args); | ||
if (is_def(path)) | ||
return path; | ||
} | ||
} | ||
} : { | ||
r: new RegExp(xs.map(function (_a) { | ||
var r = _a.r; | ||
return unwrapRe(r).source; | ||
}).join('|')), | ||
p: function (v) { | ||
for (var i = 0; i < xs.length; i++) { | ||
if (is_def(v)) { | ||
var m = xs[i].r.exec(v); | ||
if (!is_def(m)) | ||
continue; | ||
} | ||
var r = xs[i].p(v); | ||
if (r.$) | ||
return r; | ||
} | ||
return none(); | ||
}, | ||
b: function (v) { | ||
for (var i = 0; i < xs.length; i++) { | ||
var r = xs[i].b(v); | ||
if (is_def(r)) | ||
return r; | ||
} | ||
} | ||
}; | ||
} | ||
export function route_and() { | ||
export function seq() { | ||
var rs = []; | ||
@@ -99,7 +197,7 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
return { | ||
parse: function (path) { | ||
m: function (path) { | ||
var args = {}; | ||
for (var i = 0; i < rs.length; i++) { | ||
var res = rs[i].parse(path); | ||
if (res === undefined) | ||
var res = rs[i].m(path); | ||
if (!is_def(res)) | ||
return; | ||
@@ -111,7 +209,7 @@ args = tslib_1.__assign({}, args, res[0]); | ||
}, | ||
build: function (args) { | ||
f: function (args) { | ||
var path = ''; | ||
for (var i = 0; i < rs.length; i++) { | ||
var part = rs[i].build(args); | ||
if (part === undefined) | ||
var part = rs[i].f(args); | ||
if (!is_def(part)) | ||
return; | ||
@@ -124,6 +222,7 @@ path += part; | ||
} | ||
export function router_match(routes, path) { | ||
// Router | ||
export function matchs(routes, path) { | ||
var state; | ||
for (var id in routes) { | ||
var args = route_match(routes[id], path); | ||
var args = match(routes[id], path); | ||
if (args) { | ||
@@ -137,49 +236,64 @@ if (!state) | ||
} | ||
export function router_build(routes, state) { | ||
export function builds(routes, state) { | ||
for (var id in state) { | ||
var args = state[id]; | ||
if (args !== undefined) { | ||
return route_build(routes[id], args); | ||
if (is_def(args)) { | ||
return build(routes[id], args); | ||
} | ||
} | ||
} | ||
export var baseTypes = { | ||
str: { | ||
parse: function (path) { | ||
var m = path.match(/^([^\/\?]+)(.*)$/); | ||
if (m) | ||
return [decodeURIComponent(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return typeof arg == 'string' ? encodeURIComponent(arg) : undefined; } | ||
}, | ||
num: { | ||
parse: function (path) { | ||
var m = path.match(/^(\-?\d+(?:\.\d+)?)(.*)$/); | ||
if (m) | ||
return [parseFloat(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return typeof arg == 'number' ? "" + arg : undefined; }, | ||
} | ||
// Basic types | ||
export var str = { | ||
r: /^[^\/\?]+/, | ||
p: function (v) { return is_def(v) ? some(decodeURIComponent(v)) : none(); }, | ||
b: function (v) { return typeof v == 'string' ? encodeURIComponent(v) : un_def; }, | ||
}; | ||
export var num = { | ||
r: /^\-?\d+(?:\.\d+)?/, | ||
p: function (v) { return is_def(v) ? some(parseFloat(v)) : none(); }, | ||
b: function (v) { return typeof v ? "" + arg : un_def; }, | ||
}; | ||
export var und = { | ||
r: /^/, | ||
p: function () { return some(un_def); }, | ||
b: function () { return ''; } | ||
}; | ||
// Numeric types | ||
function is_int(arg) { | ||
return typeof arg == 'number' && isFinite(arg) && !(arg % 1); | ||
} | ||
export var numTypes = { | ||
int: { | ||
parse: function (path) { | ||
var m = path.match(/^(\-?\d+)(.*)$/); | ||
if (m) | ||
return [parseInt(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return is_int(arg) ? "" + arg : undefined; } | ||
}, | ||
nat: { | ||
parse: function (path) { | ||
var m = path.match(/^(\d+)(.*)$/); | ||
if (m) | ||
return [parseInt(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return is_int(arg) && arg >= 0 ? "" + arg : undefined; } | ||
} | ||
export var int = { | ||
r: /^\-?\d+/, | ||
p: function (v) { return is_def(v) ? some(parseInt(v)) : none(); }, | ||
b: function (v) { return is_int(v) ? "" + v : un_def; } | ||
}; | ||
export var nat = { | ||
r: /^\d+/, | ||
p: function (v) { return is_def(v) ? some(parseInt(v)) : none(); }, | ||
b: function (v) { return is_int(v) && v >= 0 ? "" + v : un_def; } | ||
}; | ||
// Type modifiers | ||
export function opt(_a) { | ||
var r = _a.r, p = _a.p, b = _a.b; | ||
return { | ||
r: r, | ||
p: function (v) { return is_def(v) ? p(v) : some(un_def); }, | ||
b: function (v) { return is_def(v) ? b(v) : un_def; }, | ||
}; | ||
} | ||
export function def(_a, d) { | ||
var r = _a.r, p = _a.p, b = _a.b; | ||
return { | ||
r: r, | ||
p: function (v) { return is_def(v) ? p(v) : some(d); }, | ||
b: function (v) { return v !== d ? b(v) : un_def; }, | ||
}; | ||
} | ||
var unwrapRe = 'flags' in RegExp.prototype ? | ||
function (regexp) { return regexp; } : function (regexp) { | ||
var strexp = regexp.toString(); | ||
var flags = /[gimuy]*$/.exec(strexp)[0]; | ||
var source = strexp.substring(1, strexp.length - 1 - flags.length); | ||
return { source: source, flags: flags }; | ||
}; | ||
//# sourceMappingURL=router.js.map |
{ | ||
"name": "literium-router", | ||
"version": "0.1.1", | ||
"version": "0.2.0", | ||
"description": "Type-safe router module for Literium web-framework.", | ||
@@ -32,3 +32,6 @@ "main": "router.js", | ||
"literium", | ||
"framework" | ||
"framework", | ||
"typescript", | ||
"es6", | ||
"es2015" | ||
], | ||
@@ -51,4 +54,5 @@ "author": "K. <kayo@illumium.org>", | ||
"dependencies": { | ||
"tslib": "^1.9.0" | ||
"tslib": "^1.9.0", | ||
"literium-base": "^0.2.0" | ||
} | ||
} |
189
README.md
@@ -1,3 +0,9 @@ | ||
# Type-safe router for Literium web-framework | ||
# Type-safe router | ||
[](https://badge.fury.io/js/literium-router) | ||
[](https://www.npmjs.com/package/literium-router) | ||
[](https://travis-ci.org/katyo/literium) | ||
This project is part of **Literium** WEB-framework but can be used standalone. | ||
## Why | ||
@@ -23,18 +29,20 @@ | ||
### String route | ||
### Atomic routes | ||
#### Route with static path-piece | ||
In simplest case you can use path string to create routes. | ||
```typescript | ||
import { route_str, route_match, route_build } from 'literium-router'; | ||
import { dir, match, build } from 'literium-router'; | ||
const blog = route_str('/blog'); | ||
const blog = dir('/blog'); | ||
// => Route<{}> | ||
route_match(blog, '/blog') // => {} | ||
route_match(blog, '/blog/1') // => undefined | ||
route_match(blog, '/other') // => undefined | ||
match(blog, '/blog') // => {} | ||
match(blog, '/blog/1') // => undefined | ||
match(blog, '/other') // => undefined | ||
route_build(blog, {}) // => '/blog' | ||
route_build(blog, {id: 1}) // error (extra 'id' property) | ||
build(blog, {}) // => '/blog' | ||
build(blog, {id: 1}) // error (extra 'id' property) | ||
``` | ||
@@ -44,3 +52,3 @@ | ||
### Route with argument | ||
#### Route with argument | ||
@@ -50,38 +58,60 @@ When you want handle some data in the path string you can create route with the typed argument. | ||
```typescript | ||
import { route_arg, route_match, route_build, baseTypes } from 'literium-router'; | ||
import { num, arg, match, build } from 'literium-router'; | ||
const blog_id = route_arg({id: 'num'}, baseTypes); | ||
const blog_id = arg({id: num}); | ||
// => Route<{id: number}> | ||
route_match(blog_id, '1') // => {id:1} | ||
route_match(blog_id, 'other') // => undefined | ||
route_match(blog_id, 'blog/1') // => undefined | ||
match(blog_id, '1') // => {id:1} | ||
match(blog_id, 'other') // => undefined | ||
match(blog_id, 'blog/1') // => undefined | ||
route_build(blog_id, {}) // error (missing 'id' property) | ||
route_build(blog_id, {id: 1}) // => '1' | ||
build(blog_id, {}) // error (missing 'id' property) | ||
build(blog_id, {id: 1}) // => '1' | ||
``` | ||
The first argument of `route_arg()` is the object with property name as key and with property type-tag as value. | ||
The available type-tags and corresponding value types is defined by the second argument of `route_arg()`. | ||
The first argument of `arg()` is the object with property name as key and with property type-tag as value. | ||
The available type-tags and corresponding value types is defined by the second argument of `arg()`. | ||
### Complex routes | ||
#### Query string arguments | ||
To build complex routes you can use `route_and()` to sequentially combine sub-routes. | ||
To deal with query string you can use `query()`. | ||
```typescript | ||
import { route_str, route_arg, route_and, route_match, route_build, baseTypes } from 'literium-router'; | ||
import { num, query, match, build } from 'literium-router'; | ||
const blog_by_id = route_and(route_str('/blog/'), route_arg({id: 'num'}, baseTypes); | ||
const blog_posts = query({offset: num, length: num}); | ||
// => Route<{offset: number, length: number}> | ||
match(blog_posts, '?offset=10&length=5') // => {offset:10,length:5} | ||
match(blog_posts, '?length=5&offset=10') // => {offset:10,length:5} | ||
match(blog_posts, '?length=5') // => undefined (no length arg) | ||
build(blog_posts, {length:5}) // error (missing 'offset' property) | ||
build(blog_posts, {offset:10, length:5}) // => '?offset=10&length=5' | ||
``` | ||
When you need process different query strings you can alternate queryes using [variants](#route-variants). | ||
### Route combinators | ||
#### Sequential | ||
To build complex routes you can use `seq()` to sequentially combine sub-routes. | ||
```typescript | ||
import { num, dir, arg, seq, match, build } from 'literium-router'; | ||
const blog_by_id = seq(dir('/blog/'), arg({id: num}); | ||
// => Route<{id: number}> | ||
route_match(blog_by_id, '/blog/1') // => {id:1} | ||
route_match(blog_by_id, '/blog/1/') // => undefined | ||
route_match(blog_by_id, '/other') // => undefined | ||
route_match(blog_by_id, '1') // => undefined | ||
match(blog_by_id, '/blog/1') // => {id:1} | ||
match(blog_by_id, '/blog/1/') // => undefined | ||
match(blog_by_id, '/other') // => undefined | ||
match(blog_by_id, '1') // => undefined | ||
route_build(blog_by_id, {}) // error (missing 'id' property) | ||
route_build(blog_by_id, {id: 1}) // => '/blog/1' | ||
build(blog_by_id, {}) // error (missing 'id' property) | ||
build(blog_by_id, {id: 1}) // => '/blog/1' | ||
``` | ||
### Route variants | ||
#### Variants | ||
@@ -91,22 +121,22 @@ And of course you can combine some number of routes which can be used alternatively. | ||
```typescript | ||
import { route_str, route_arg, route_and, route_match, route_build, baseTypes } from 'literium-router'; | ||
import { str, num, dir, arg, seq, alt, match, build } from 'literium-router'; | ||
const blogs_by_tag = route_and(route_str('/blog/tag-'), route_arg(baseTypes, {id: 'str'})); | ||
const blogs_by_tag = seq(dir('/blog/tag-'), arg({id: str})); | ||
// => Route<{id: string}> | ||
const by_author = route_and(route_str('/author-'), route_arg(baseTypes, {user: 'num'})); | ||
const by_author = seq(dir('/author-'), arg({user: num})); | ||
// => Route<{user: number}> | ||
const blogs_by_tag_opt_by_author = route_and(blogs_by_tag, route_or(by_author, route_str(''))); | ||
const blogs_by_tag_opt_by_author = seq(blogs_by_tag, alt(by_author, dir(''))); | ||
// => Route<{tag: string} | {tag: string} & {user: number}> | ||
route_match(blogs_by_tag_opt_by_author, '/blog/tag-js') // => {tag:"js"} | ||
route_match(blogs_by_tag_opt_by_author, '/blog/tag-js/author-3') // => {tag:"js",user:3} | ||
route_match(blogs_by_tag_opt_by_author, '/blog/tag-js/') // => undefined | ||
route_match(blogs_by_tag_opt_by_author, '/blog/tag-js/author-') // => undefined | ||
route_match(blogs_by_tag_opt_by_author, '/other') // => undefined | ||
match(blogs_by_tag_opt_by_author, '/blog/tag-js') // => {tag:"js"} | ||
match(blogs_by_tag_opt_by_author, '/blog/tag-js/author-3') // => {tag:"js",user:3} | ||
match(blogs_by_tag_opt_by_author, '/blog/tag-js/') // => undefined | ||
match(blogs_by_tag_opt_by_author, '/blog/tag-js/author-') // => undefined | ||
match(blogs_by_tag_opt_by_author, '/other') // => undefined | ||
route_build(blogs_by_tag_opt_by_author, {}) // error (missing 'tag' property) | ||
route_build(blogs_by_tag_opt_by_author, {tag:"git"}) // => '/blog/tag-git' | ||
route_build(blogs_by_tag_opt_by_author, {user:3}) // error (missing 'tag' property) | ||
route_build(blogs_by_tag_opt_by_author, {tag:"git",user:3}) // => '/blog/tag-git/author-3' | ||
build(blogs_by_tag_opt_by_author, {}) // error (missing 'tag' property) | ||
build(blogs_by_tag_opt_by_author, {tag:"git"}) // => '/blog/tag-git' | ||
build(blogs_by_tag_opt_by_author, {user:3}) // error (missing 'tag' property) | ||
build(blogs_by_tag_opt_by_author, {tag:"git",user:3}) // => '/blog/tag-git/author-3' | ||
``` | ||
@@ -117,3 +147,3 @@ | ||
### Argument types | ||
### Custom route types | ||
@@ -124,3 +154,3 @@ One of the more helpful feature of this router is the possibility to define your own argument types. | ||
```typescript | ||
import { route_str, route_arg, route_and, route_match, route_build, TypeApi } from 'literium-router'; | ||
import { dir, arg, seq, match, build, Route } from 'literium-router'; | ||
@@ -130,33 +160,26 @@ // Our enum type | ||
// The type-tag to type mapping | ||
export interface OrderType { | ||
ord: Order; | ||
} | ||
// The implementation of TypeApi | ||
export const orderType: TypeApi<OrderType> = { | ||
ord: { | ||
// The parser function (path => value) | ||
parse: path => { | ||
const m = path.match(/^(asc|desc)(.*)$/); | ||
if (m) return [m[1] == 'asc' ? Order.Asc : Order.Desc, m[2]]; | ||
}, | ||
// The builder function (value => path) | ||
build: arg => arg === Order.Asc || arg === Order.Desc ? | ||
`${arg == Order.Asc ? 'asc' : 'desc'}` : undefined | ||
// The implementation of Route | ||
export const ord: Route<Order> = { | ||
// The parser function (path => value) | ||
p: path => { | ||
const m = path.match(/^(asc|desc)(.*)$/); | ||
if (m) return [m[1] == 'asc' ? Order.Asc : Order.Desc, m[2]]; | ||
}, | ||
// The builder function (value => path) | ||
b: arg => arg === Order.Asc || arg === Order.Desc ? | ||
`${arg == Order.Asc ? 'asc' : 'desc'}` : undefined | ||
}; | ||
const blogs_by_date = route_and(route_str('/blog/date-'), route_arg(orderType, {sort: 'ord'})); | ||
const blogs_by_date = seq(dir('/blog/date-'), arg({sort: ord})); | ||
// => Route<{sort: Order}> | ||
route_match(blogs_by_date, '/blog/date-asc') // => {sort:Order.Asc} | ||
route_match(blogs_by_date, '/blog/date-desc') // => {sort:Order.Desc} | ||
route_match(blogs_by_date, '/blog/date-') // => undefined | ||
route_match(blogs_by_date, '/blog/date-other') // => undefined | ||
match(blogs_by_date, '/blog/date-asc') // => {sort:Order.Asc} | ||
match(blogs_by_date, '/blog/date-desc') // => {sort:Order.Desc} | ||
match(blogs_by_date, '/blog/date-') // => undefined | ||
match(blogs_by_date, '/blog/date-other') // => undefined | ||
route_build(blogs_by_date, {sort:Order.Asc}) // => '/blog/date-asc' | ||
route_build(blogs_by_date, {sort:Order.Desc}) // => '/blog/date-desc' | ||
route_build(blogs_by_date, {}) // error (missing 'sort' property) | ||
route_build(blogs_by_date, {sort:'asc'}) // error (type mismatch of 'sort' property) | ||
build(blogs_by_date, {sort:Order.Asc}) // => '/blog/date-asc' | ||
build(blogs_by_date, {sort:Order.Desc}) // => '/blog/date-desc' | ||
build(blogs_by_date, {}) // error (missing 'sort' property) | ||
build(blogs_by_date, {sort:'asc'}) // error (type mismatch of 'sort' property) | ||
``` | ||
@@ -167,3 +190,3 @@ | ||
Usually in real-life applications we don't like to operate with routes separately. | ||
One of ways to works with all defined routes together is using of the methods `router_match()` and `router_build()`. | ||
One of ways to works with all defined routes together is using of the methods `matchs()` and `builds()`. | ||
@@ -174,17 +197,17 @@ This methods gets the object with routes names as keys and routes itself as values. | ||
```typescript | ||
import { route_str, route_arg, route_and, router_match, router_build, baseTypes } from 'literium-router'; | ||
import { num, str, dir, arg, seq, matchs, builds } from 'literium-router'; | ||
const root = route_str('/'); | ||
const blog_by_id = route_and(root, route_str('blog/'), route_arg({id:'num'}, baseTypes)); | ||
const blogs_by_tag = route_and(root, route_str('blog/tag-'), route_arg({tag:'str'}, baseTypes)); | ||
const root = dir('/'); | ||
const blog_by_id = seq(root, dir('blog/'), arg({id:num})); | ||
const blogs_by_tag = seq(root, dir('blog/tag-'), arg({tag:str})); | ||
const routes = { root, blogs_by_tag, blog_by_id }; | ||
router_match(routes, '/') // => {root:{}} | ||
router_match(routes, '/blog/2') // => {blog_by_id:{id:2}} | ||
router_match(routes, '/blog/tag-es6') // => {blogs_by_tag:{tag:"es6"}} | ||
matchs(routes, '/') // => {root:{}} | ||
matchs(routes, '/blog/2') // => {blog_by_id:{id:2}} | ||
matchs(routes, '/blog/tag-es6') // => {blogs_by_tag:{tag:"es6"}} | ||
router_build(routes, {root:{}}) // => '/' | ||
router_build(routes, {blog_by_id:{id:2}}) // => '/blog/2' | ||
router_build(routes, {blogs_by_tag:{tag:"es6"}}) // => '/blog/tag-es6' | ||
builds(routes, {root:{}}) // => '/' | ||
builds(routes, {blog_by_id:{id:2}}) // => '/blog/2' | ||
builds(routes, {blogs_by_tag:{tag:"es6"}}) // => '/blog/tag-es6' | ||
``` | ||
@@ -195,5 +218,1 @@ | ||
The _TypeScript 2.7.x_ have an [issue](https://github.com/Microsoft/TypeScript/issues/22169) which breaks the type inference of object values, so I strongly recommend to use _TypeScript 2.6.x_ until _TypeScript 2.8.x_ has been released. | ||
## Todo | ||
* Handling search parameters |
121
router.d.ts
@@ -1,63 +0,68 @@ | ||
export interface PathArg<TypeMap> { | ||
[name: string]: keyof TypeMap; | ||
import { Option } from 'literium-base'; | ||
export interface Route<Args> { | ||
m(s: string): [Args, string] | void; | ||
f(v: Args): string | void; | ||
} | ||
export declare type ArgMap<TypeMap, Arg extends PathArg<TypeMap>> = { | ||
[Name in keyof Arg]: TypeMap[Arg[Name]]; | ||
}; | ||
export interface TypeImpl<Type> { | ||
parse(path: string): [Type, string] | void; | ||
build(arg: Type): string | void; | ||
export interface ArgType<Type> { | ||
r: RegExp; | ||
p(s: string | void): Option<Type>; | ||
b(v: Type): string | void; | ||
} | ||
export declare type TypeApi<TypeMap> = { | ||
[Tag in keyof TypeMap]: TypeImpl<TypeMap[Tag]>; | ||
}; | ||
export interface Route<Args> { | ||
parse(path: string): [Args, string] | void; | ||
build(args: Args): string | void; | ||
} | ||
export declare type Routes<State> = { | ||
[Id in keyof State]: Route<State[Id]>; | ||
}; | ||
export declare function type_and<TypeMap1, TypeMap2>(api1: TypeApi<TypeMap1>, api2: TypeApi<TypeMap2>): TypeApi<TypeMap1 & TypeMap2>; | ||
export declare function route_match<Args>(route: Route<Args>, path: string): Args | void; | ||
export declare function route_build<Args, ActualArgs extends Args>(route: Route<Args>, args: ActualArgs & Args): string; | ||
export declare function route_str(path: string): Route<{}>; | ||
export declare function route_def<Arg>(arg: Arg): Route<Arg>; | ||
export declare function route_arg<TypeMap, Arg extends PathArg<TypeMap>>(arg: Arg, type_api: TypeApi<TypeMap>): Route<ArgMap<TypeMap, Arg>>; | ||
export declare function route_or<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 | Args2>; | ||
export declare function route_or<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 | Args2 | Args3>; | ||
export declare function route_or<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 | Args2 | Args3 | Args4>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 | Args2 | Args3 | Args4 | Args5>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function route_and<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 & Args2>; | ||
export declare function route_and<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 & Args2 & Args3>; | ||
export declare function route_and<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 & Args2 & Args3 & Args4>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 & Args2 & Args3 & Args4 & Args5>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15>; | ||
export declare function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15, Args16>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>, r16: Route<Args16>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15 & Args16>; | ||
export declare function router_match<State>(routes: Routes<State>, path: string): Partial<State> | void; | ||
export declare function router_build<State>(routes: Routes<State>, state: Partial<State>): string | void; | ||
export interface BaseTypes { | ||
str: string; | ||
num: number; | ||
} | ||
export declare const baseTypes: TypeApi<BaseTypes>; | ||
export interface NumTypes { | ||
nat: number; | ||
int: number; | ||
} | ||
export declare const numTypes: TypeApi<NumTypes>; | ||
export declare function match<Args>({m}: Route<Args>, path: string): Args | void; | ||
export declare function build<Args, ActualArgs extends Args>({f}: Route<Args>, args: ActualArgs & Args): string; | ||
export declare function dir(path: string): Route<{}>; | ||
export declare function ins<Arg>(arg: Arg): Route<Arg>; | ||
export declare type ArgMap<TypeMap> = { | ||
[Tag in keyof TypeMap]: ArgType<TypeMap[Tag]>; | ||
}; | ||
export declare function arg<TypeMap>(arg: ArgMap<TypeMap>): Route<TypeMap>; | ||
export declare type QueryArgs = Record<string, string | void>; | ||
export declare function query_parse(str: string): QueryArgs; | ||
export declare function query_build(args: QueryArgs): string; | ||
export declare function query<TypeMap>(arg: ArgMap<TypeMap>, qmark?: boolean): Route<TypeMap>; | ||
export declare function alt<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 | Args2>; | ||
export declare function alt<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 | Args2 | Args3>; | ||
export declare function alt<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 | Args2 | Args3 | Args4>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 | Args2 | Args3 | Args4 | Args5>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export declare function alt<Type1, Type2>(t1: ArgType<Type1>, t2: ArgType<Type2>): ArgType<Type1 | Type2>; | ||
export declare function alt<Type1, Type2, Type3>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>): ArgType<Type1 | Type2 | Type3>; | ||
export declare function alt<Type1, Type2, Type3, Type4>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>): ArgType<Type1 | Type2 | Type3 | Type4>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>, t9: ArgType<Type9>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9>; | ||
export declare function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>, t9: ArgType<Type9>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9>; | ||
export declare function seq<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 & Args2>; | ||
export declare function seq<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 & Args2 & Args3>; | ||
export declare function seq<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 & Args2 & Args3 & Args4>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 & Args2 & Args3 & Args4 & Args5>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15>; | ||
export declare function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15, Args16>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>, r16: Route<Args16>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15 & Args16>; | ||
export declare function matchs<State>(routes: Routes<State>, path: string): Partial<State> | void; | ||
export declare function builds<State>(routes: Routes<State>, state: Partial<State>): string | void; | ||
export declare const str: ArgType<string>; | ||
export declare const num: ArgType<number>; | ||
export declare const und: ArgType<void>; | ||
export declare const int: ArgType<number>; | ||
export declare const nat: ArgType<number>; | ||
export declare function opt<Type>({r, p, b}: ArgType<Type>): ArgType<Type | void>; | ||
export declare function def<Type>({r, p, b}: ArgType<Type>, d: Type): ArgType<Type>; |
310
router.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
var tslib_1 = require("tslib"); | ||
function type_and(api1, api2) { | ||
return tslib_1.__assign({}, api1, api2); | ||
var literium_base_1 = require("literium-base"); | ||
var un_def = undefined; | ||
function is_def(v) { | ||
return v != un_def; | ||
} | ||
exports.type_and = type_and; | ||
function route_match(route, path) { | ||
var res = route.parse(path); | ||
if (!res || res[1] != '') | ||
function match(_a, path) { | ||
var m = _a.m; | ||
var r = m(path); | ||
if (!r || r[1] != '') | ||
return; | ||
return res[0]; | ||
return r[0]; | ||
} | ||
exports.route_match = route_match; | ||
exports.match = match; | ||
// The trick with ActualArgs type parameter makes passed arguments to be the same as route expects. | ||
// Without it the compiler leads the type of the route to the type of arguments. | ||
// Also it is important the arguments must be of the type 'ActualArgs & Args', because we cannot set type condition 'ActualArgs = Args'. | ||
function route_build(route, args) { | ||
var path = route.build(args); | ||
if (path === undefined) | ||
function build(_a, args) { | ||
var f = _a.f; | ||
var path = f(args); | ||
if (!is_def(path)) | ||
throw "Cannot build path"; | ||
return path; | ||
} | ||
exports.route_build = route_build; | ||
function route_str(path) { | ||
exports.build = build; | ||
function dir(path) { | ||
var ent = encodeURI(path); | ||
return { | ||
parse: function (path) { return path.substr(0, ent.length) == ent ? | ||
[{}, path.substr(ent.length)] : undefined; }, | ||
build: function () { return ent; } | ||
m: function (path) { return path.substr(0, ent.length) == ent ? | ||
[{}, path.substr(ent.length)] : un_def; }, | ||
f: function () { return ent; } | ||
}; | ||
} | ||
exports.route_str = route_str; | ||
function route_def(arg) { | ||
exports.dir = dir; | ||
function ins(arg) { | ||
return { | ||
parse: function (path) { return [arg, path]; }, | ||
build: function (args) { | ||
m: function (path) { return [arg, path]; }, | ||
f: function (args) { | ||
for (var key in arg) { | ||
@@ -46,11 +49,7 @@ if (!(key in args) || args[key] !== arg[key]) | ||
} | ||
exports.route_def = route_def; | ||
function route_arg(arg, type_api) { | ||
exports.ins = ins; | ||
function arg(arg) { | ||
var key; | ||
var tag; | ||
var api; | ||
for (var fld in arg) { | ||
key = fld; | ||
tag = arg[key]; | ||
api = type_api[tag]; | ||
break; | ||
@@ -60,43 +59,144 @@ } | ||
throw "No arg"; | ||
var _a = arg[key], r = _a.r, p = _a.p, b = _a.b; | ||
return { | ||
parse: function (path) { | ||
var res = api.parse(path); | ||
if (!res) | ||
m: function (path) { | ||
var res = r.exec(path); | ||
if (!is_def(res)) | ||
return; | ||
var val = res[0], rest = res[1]; | ||
return [(_a = {}, _a[key] = val, _a), rest]; | ||
var val = p(res[0]); | ||
if (!val.$) | ||
return; | ||
return [ | ||
(_a = {}, _a[key] = val._, _a), | ||
path.slice(res[0].length) | ||
]; | ||
var _a; | ||
}, | ||
build: function (args) { | ||
f: function (args) { | ||
if (!(key in args)) | ||
return; | ||
return api.build(args[key]); | ||
return b(args[key]); | ||
} | ||
}; | ||
} | ||
exports.route_arg = route_arg; | ||
function route_or() { | ||
var rs = []; | ||
exports.arg = arg; | ||
function query_parse(str) { | ||
var args = {}; | ||
if (str == '') | ||
return args; | ||
for (var _i = 0, _a = str.split(/&/); _i < _a.length; _i++) { | ||
var arg_1 = _a[_i]; | ||
var pair = arg_1.split(/=/); | ||
args[decodeURIComponent(pair[0])] = pair.length > 1 ? pair[1] : un_def; | ||
} | ||
return args; | ||
} | ||
exports.query_parse = query_parse; | ||
function query_build(args) { | ||
var strs = []; | ||
for (var name in args) { | ||
var value = args[name]; | ||
strs.push("" + encodeURIComponent(name) + (typeof value == 'string' ? "=" + value : '')); | ||
} | ||
return strs.join('&'); | ||
} | ||
exports.query_build = query_build; | ||
function query(arg, qmark) { | ||
if (qmark === void 0) { qmark = true; } | ||
var key; | ||
for (var fld in arg) { | ||
key = fld; | ||
break; | ||
} | ||
if (!key) | ||
throw "No args"; | ||
return { | ||
m: function (path) { | ||
if (qmark && path.charAt(0) != '?') | ||
return; | ||
var qargs = query_parse(qmark ? path.substring(1) : path); | ||
var args = {}; | ||
for (var key_1 in arg) { | ||
var _a = arg[key_1], r = _a.r, p = _a.p; | ||
var str_1 = qargs[key_1]; | ||
if (is_def(str_1)) { | ||
// check string value using regexp | ||
var res_ = r.exec(str_1); | ||
if (!is_def(res_) || | ||
res_[0].length != str_1.length) | ||
return; | ||
} | ||
var val = p(str_1); | ||
if (!val.$) | ||
return; | ||
if (is_def(val._)) | ||
args[key_1] = val._; | ||
} | ||
return [args, '']; | ||
}, | ||
f: function (args) { | ||
var qargs = {}; | ||
for (var key_2 in arg) { | ||
if (!(key_2 in args)) | ||
return; | ||
var b = arg[key_2].b; | ||
var val = b(args[key_2]); | ||
if (is_def(val)) | ||
qargs[key_2] = val; | ||
} | ||
var qstr = query_build(qargs); | ||
return "" + (qmark && qstr ? '?' : '') + qstr; | ||
} | ||
}; | ||
} | ||
exports.query = query; | ||
function alt() { | ||
var xs = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
rs[_i] = arguments[_i]; | ||
xs[_i] = arguments[_i]; | ||
} | ||
return { | ||
parse: function (path) { | ||
for (var i = 0; i < rs.length; i++) { | ||
var res = rs[i].parse(path); | ||
if (res !== undefined) | ||
return xs[0].m ? { | ||
m: function (path) { | ||
for (var i = 0; i < xs.length; i++) { | ||
var res = xs[i].m(path); | ||
if (is_def(res)) | ||
return res; | ||
} | ||
}, | ||
build: function (args) { | ||
for (var i = 0; i < rs.length; i++) { | ||
var path = rs[i].build(args); | ||
if (path !== undefined) | ||
f: function (args) { | ||
for (var i = 0; i < xs.length; i++) { | ||
var path = xs[i].f(args); | ||
if (is_def(path)) | ||
return path; | ||
} | ||
} | ||
} : { | ||
r: new RegExp(xs.map(function (_a) { | ||
var r = _a.r; | ||
return unwrapRe(r).source; | ||
}).join('|')), | ||
p: function (v) { | ||
for (var i = 0; i < xs.length; i++) { | ||
if (is_def(v)) { | ||
var m = xs[i].r.exec(v); | ||
if (!is_def(m)) | ||
continue; | ||
} | ||
var r = xs[i].p(v); | ||
if (r.$) | ||
return r; | ||
} | ||
return literium_base_1.none(); | ||
}, | ||
b: function (v) { | ||
for (var i = 0; i < xs.length; i++) { | ||
var r = xs[i].b(v); | ||
if (is_def(r)) | ||
return r; | ||
} | ||
} | ||
}; | ||
} | ||
exports.route_or = route_or; | ||
function route_and() { | ||
exports.alt = alt; | ||
function seq() { | ||
var rs = []; | ||
@@ -107,7 +207,7 @@ for (var _i = 0; _i < arguments.length; _i++) { | ||
return { | ||
parse: function (path) { | ||
m: function (path) { | ||
var args = {}; | ||
for (var i = 0; i < rs.length; i++) { | ||
var res = rs[i].parse(path); | ||
if (res === undefined) | ||
var res = rs[i].m(path); | ||
if (!is_def(res)) | ||
return; | ||
@@ -119,7 +219,7 @@ args = tslib_1.__assign({}, args, res[0]); | ||
}, | ||
build: function (args) { | ||
f: function (args) { | ||
var path = ''; | ||
for (var i = 0; i < rs.length; i++) { | ||
var part = rs[i].build(args); | ||
if (part === undefined) | ||
var part = rs[i].f(args); | ||
if (!is_def(part)) | ||
return; | ||
@@ -132,7 +232,8 @@ path += part; | ||
} | ||
exports.route_and = route_and; | ||
function router_match(routes, path) { | ||
exports.seq = seq; | ||
// Router | ||
function matchs(routes, path) { | ||
var state; | ||
for (var id in routes) { | ||
var args = route_match(routes[id], path); | ||
var args = match(routes[id], path); | ||
if (args) { | ||
@@ -146,51 +247,68 @@ if (!state) | ||
} | ||
exports.router_match = router_match; | ||
function router_build(routes, state) { | ||
exports.matchs = matchs; | ||
function builds(routes, state) { | ||
for (var id in state) { | ||
var args = state[id]; | ||
if (args !== undefined) { | ||
return route_build(routes[id], args); | ||
if (is_def(args)) { | ||
return build(routes[id], args); | ||
} | ||
} | ||
} | ||
exports.router_build = router_build; | ||
exports.baseTypes = { | ||
str: { | ||
parse: function (path) { | ||
var m = path.match(/^([^\/\?]+)(.*)$/); | ||
if (m) | ||
return [decodeURIComponent(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return typeof arg == 'string' ? encodeURIComponent(arg) : undefined; } | ||
}, | ||
num: { | ||
parse: function (path) { | ||
var m = path.match(/^(\-?\d+(?:\.\d+)?)(.*)$/); | ||
if (m) | ||
return [parseFloat(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return typeof arg == 'number' ? "" + arg : undefined; }, | ||
} | ||
exports.builds = builds; | ||
// Basic types | ||
exports.str = { | ||
r: /^[^\/\?]+/, | ||
p: function (v) { return is_def(v) ? literium_base_1.some(decodeURIComponent(v)) : literium_base_1.none(); }, | ||
b: function (v) { return typeof v == 'string' ? encodeURIComponent(v) : un_def; }, | ||
}; | ||
exports.num = { | ||
r: /^\-?\d+(?:\.\d+)?/, | ||
p: function (v) { return is_def(v) ? literium_base_1.some(parseFloat(v)) : literium_base_1.none(); }, | ||
b: function (v) { return typeof v ? "" + arg : un_def; }, | ||
}; | ||
exports.und = { | ||
r: /^/, | ||
p: function () { return literium_base_1.some(un_def); }, | ||
b: function () { return ''; } | ||
}; | ||
// Numeric types | ||
function is_int(arg) { | ||
return typeof arg == 'number' && isFinite(arg) && !(arg % 1); | ||
} | ||
exports.numTypes = { | ||
int: { | ||
parse: function (path) { | ||
var m = path.match(/^(\-?\d+)(.*)$/); | ||
if (m) | ||
return [parseInt(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return is_int(arg) ? "" + arg : undefined; } | ||
}, | ||
nat: { | ||
parse: function (path) { | ||
var m = path.match(/^(\d+)(.*)$/); | ||
if (m) | ||
return [parseInt(m[1]), m[2]]; | ||
}, | ||
build: function (arg) { return is_int(arg) && arg >= 0 ? "" + arg : undefined; } | ||
} | ||
exports.int = { | ||
r: /^\-?\d+/, | ||
p: function (v) { return is_def(v) ? literium_base_1.some(parseInt(v)) : literium_base_1.none(); }, | ||
b: function (v) { return is_int(v) ? "" + v : un_def; } | ||
}; | ||
exports.nat = { | ||
r: /^\d+/, | ||
p: function (v) { return is_def(v) ? literium_base_1.some(parseInt(v)) : literium_base_1.none(); }, | ||
b: function (v) { return is_int(v) && v >= 0 ? "" + v : un_def; } | ||
}; | ||
// Type modifiers | ||
function opt(_a) { | ||
var r = _a.r, p = _a.p, b = _a.b; | ||
return { | ||
r: r, | ||
p: function (v) { return is_def(v) ? p(v) : literium_base_1.some(un_def); }, | ||
b: function (v) { return is_def(v) ? b(v) : un_def; }, | ||
}; | ||
} | ||
exports.opt = opt; | ||
function def(_a, d) { | ||
var r = _a.r, p = _a.p, b = _a.b; | ||
return { | ||
r: r, | ||
p: function (v) { return is_def(v) ? p(v) : literium_base_1.some(d); }, | ||
b: function (v) { return v !== d ? b(v) : un_def; }, | ||
}; | ||
} | ||
exports.def = def; | ||
var unwrapRe = 'flags' in RegExp.prototype ? | ||
function (regexp) { return regexp; } : function (regexp) { | ||
var strexp = regexp.toString(); | ||
var flags = /[gimuy]*$/.exec(strexp)[0]; | ||
var source = strexp.substring(1, strexp.length - 1 - flags.length); | ||
return { source: source, flags: flags }; | ||
}; | ||
//# sourceMappingURL=router.js.map |
@@ -1,31 +0,31 @@ | ||
// satisfy existing argument type | ||
export interface PathArg<TypeMap> { [name: string]: keyof TypeMap } | ||
import { Option, some, none } from 'literium-base'; | ||
// map argument type | ||
export type ArgMap<TypeMap, Arg extends PathArg<TypeMap>> = {[Name in keyof Arg]: TypeMap[Arg[Name]]}; | ||
export interface Route<Args> { | ||
// match path to arguments | ||
m(s: string): [Args, string] | void; | ||
// format path with arguments | ||
f(v: Args): string | void; | ||
} | ||
export interface TypeImpl<Type> { | ||
parse(path: string): [Type, string] | void; | ||
build(arg: Type): string | void; | ||
export interface ArgType<Type> { | ||
// match regexp | ||
r: RegExp; | ||
// parse argument value | ||
p(s: string | void): Option<Type>; | ||
// build argument value | ||
b(v: Type): string | void; | ||
} | ||
export type TypeApi<TypeMap> = {[Tag in keyof TypeMap]: TypeImpl<TypeMap[Tag]>}; | ||
export type Routes<State> = { [Id in keyof State]: Route<State[Id]> }; | ||
export interface Route<Args> { | ||
// match path to arguments | ||
parse(path: string): [Args, string] | void; | ||
// build path from arguments | ||
build(args: Args): string | void; | ||
} | ||
const un_def = undefined; | ||
export type Routes<State> = {[Id in keyof State]: Route<State[Id]>}; | ||
export function type_and<TypeMap1, TypeMap2>(api1: TypeApi<TypeMap1>, api2: TypeApi<TypeMap2>): TypeApi<TypeMap1 & TypeMap2> { | ||
return { ...<any>api1, ...<any>api2 }; | ||
function is_def<Type>(v: Type | void | null): v is Type { | ||
return v != un_def; | ||
} | ||
export function route_match<Args>(route: Route<Args>, path: string): Args | void { | ||
const res = route.parse(path); | ||
if (!res || res[1] != '') return; | ||
return res[0]; | ||
export function match<Args>({ m }: Route<Args>, path: string): Args | void { | ||
const r = m(path); | ||
if (!r || r[1] != '') return; | ||
return r[0]; | ||
} | ||
@@ -36,22 +36,22 @@ | ||
// Also it is important the arguments must be of the type 'ActualArgs & Args', because we cannot set type condition 'ActualArgs = Args'. | ||
export function route_build<Args, ActualArgs extends Args>(route: Route<Args>, args: ActualArgs & Args): string { | ||
const path = route.build(args); | ||
if (path === undefined) throw "Cannot build path"; | ||
export function build<Args, ActualArgs extends Args>({ f }: Route<Args>, args: ActualArgs & Args): string { | ||
const path = f(args); | ||
if (!is_def(path)) throw "Cannot build path"; | ||
return path; | ||
} | ||
export function route_str(path: string): Route<{}> { | ||
export function dir(path: string): Route<{}> { | ||
const ent: string = encodeURI(path); | ||
return { | ||
parse: path => path.substr(0, ent.length) == ent ? | ||
[{}, path.substr(ent.length)] : undefined, | ||
build: () => ent | ||
m: path => path.substr(0, ent.length) == ent ? | ||
[{}, path.substr(ent.length)] : un_def, | ||
f: () => ent | ||
}; | ||
} | ||
export function route_def<Arg>(arg: Arg): Route<Arg> { | ||
export function ins<Arg>(arg: Arg): Route<Arg> { | ||
return { | ||
parse: path => [arg, path], | ||
build: args => { | ||
m: path => [arg, path], | ||
f: args => { | ||
for (const key in arg) { | ||
@@ -65,24 +65,27 @@ if (!(key in args) || args[key] !== arg[key]) return; | ||
export function route_arg<TypeMap, Arg extends PathArg<TypeMap>>(arg: Arg, type_api: TypeApi<TypeMap>): Route<ArgMap<TypeMap, Arg>> { | ||
let key: keyof Arg | void; | ||
let tag: keyof TypeMap; | ||
let api: TypeImpl<TypeMap[keyof TypeMap]>; | ||
export type ArgMap<TypeMap> = { [Tag in keyof TypeMap]: ArgType<TypeMap[Tag]> }; | ||
export function arg<TypeMap>(arg: ArgMap<TypeMap>): Route<TypeMap> { | ||
let key: keyof TypeMap | void; | ||
for (const fld in arg) { | ||
key = fld; | ||
tag = arg[key]; | ||
api = type_api[tag]; | ||
break; | ||
} | ||
if (!key) throw "No arg"; | ||
const { r, p, b } = arg[key]; | ||
return { | ||
parse: path => { | ||
const res = api.parse(path); | ||
if (!res) return; | ||
const [val, rest] = res; | ||
return [{ [key as keyof Arg]: val } as ArgMap<TypeMap, Arg>, rest]; | ||
m: path => { | ||
const res = r.exec(path); | ||
if (!is_def(res)) return; | ||
const val = p(res[0]); | ||
if (!val.$) return; | ||
return [ | ||
{ [key as keyof TypeMap]: val._ } as any as TypeMap, | ||
path.slice(res[0].length) | ||
]; | ||
}, | ||
build: args => { | ||
f: args => { | ||
if (!(key in args)) return; | ||
return api.build(args[key as keyof Arg]); | ||
return b(args[key as keyof TypeMap]); | ||
} | ||
@@ -92,24 +95,62 @@ }; | ||
export function route_or<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 | Args2>; | ||
export function route_or<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 | Args2 | Args3>; | ||
export function route_or<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 | Args2 | Args3 | Args4>; | ||
export function route_or<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 | Args2 | Args3 | Args4 | Args5>; | ||
export function route_or<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6>; | ||
export function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7>; | ||
export function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8>; | ||
export function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export function route_or<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export function route_or(...rs: Route<object>[]): Route<object> { | ||
export type QueryArgs = Record<string, string | void>; | ||
export function query_parse(str: string): QueryArgs { | ||
const args = {} as QueryArgs; | ||
if (str == '') return args; | ||
for (const arg of str.split(/&/)) { | ||
const pair = arg.split(/=/); | ||
args[decodeURIComponent(pair[0])] = pair.length > 1 ? pair[1] : un_def; | ||
} | ||
return args; | ||
} | ||
export function query_build(args: QueryArgs): string { | ||
const strs: string[] = []; | ||
for (const name in args) { | ||
const value = args[name]; | ||
strs.push(`${encodeURIComponent(name)}${typeof value == 'string' ? `=${value}` : ''}`); | ||
} | ||
return strs.join('&'); | ||
} | ||
export function query<TypeMap>(arg: ArgMap<TypeMap>, qmark: boolean = true): Route<TypeMap> { | ||
let key: keyof TypeMap | void; | ||
for (const fld in arg) { | ||
key = fld; | ||
break; | ||
} | ||
if (!key) throw "No args"; | ||
return { | ||
parse: path => { | ||
for (let i = 0; i < rs.length; i++) { | ||
const res = rs[i].parse(path); | ||
if (res !== undefined) return res; | ||
m: path => { | ||
if (qmark && path.charAt(0) != '?') return; | ||
const qargs = query_parse(qmark ? path.substring(1) : path); | ||
const args = {} as TypeMap; | ||
for (const key in arg) { | ||
const { r, p } = arg[key]; | ||
const str = qargs[key as string]; | ||
if (is_def(str)) { | ||
// check string value using regexp | ||
const res_ = r.exec(str); | ||
if (!is_def(res_) || | ||
res_[0].length != str.length) | ||
return; | ||
} | ||
const val = p(str); | ||
if (!val.$) return; | ||
if (is_def(val._)) args[key] = val._; | ||
} | ||
return [args, '']; | ||
}, | ||
build: args => { | ||
for (let i = 0; i < rs.length; i++) { | ||
const path = rs[i].build(args); | ||
if (path !== undefined) return path; | ||
f: args => { | ||
const qargs = {} as QueryArgs; | ||
for (const key in arg) { | ||
if (!(key in args)) return; | ||
const { b } = arg[key]; | ||
const val = b(args[key]); | ||
if (is_def(val)) qargs[key] = val; | ||
} | ||
const qstr = query_build(qargs); | ||
return `${qmark && qstr ? '?' : ''}${qstr}`; | ||
} | ||
@@ -119,25 +160,83 @@ }; | ||
export function route_and<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 & Args2>; | ||
export function route_and<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 & Args2 & Args3>; | ||
export function route_and<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 & Args2 & Args3 & Args4>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 & Args2 & Args3 & Args4 & Args5>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15>; | ||
export function route_and<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15, Args16>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>, r16: Route<Args16>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15 & Args16>; | ||
export function route_and(...rs: Route<object>[]): Route<object> { | ||
// Combinators | ||
export function alt<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 | Args2>; | ||
export function alt<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 | Args2 | Args3>; | ||
export function alt<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 | Args2 | Args3 | Args4>; | ||
export function alt<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 | Args2 | Args3 | Args4 | Args5>; | ||
export function alt<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6>; | ||
export function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7>; | ||
export function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8>; | ||
export function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export function alt<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 | Args2 | Args3 | Args4 | Args5 | Args6 | Args7 | Args8 | Args9>; | ||
export function alt<Type1, Type2>(t1: ArgType<Type1>, t2: ArgType<Type2>): ArgType<Type1 | Type2>; | ||
export function alt<Type1, Type2, Type3>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>): ArgType<Type1 | Type2 | Type3>; | ||
export function alt<Type1, Type2, Type3, Type4>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>): ArgType<Type1 | Type2 | Type3 | Type4>; | ||
export function alt<Type1, Type2, Type3, Type4, Type5>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5>; | ||
export function alt<Type1, Type2, Type3, Type4, Type5, Type6>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6>; | ||
export function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7>; | ||
export function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8>; | ||
export function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>, t9: ArgType<Type9>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9>; | ||
export function alt<Type1, Type2, Type3, Type4, Type5, Type6, Type7, Type8, Type9>(t1: ArgType<Type1>, t2: ArgType<Type2>, t3: ArgType<Type3>, t4: ArgType<Type4>, t5: ArgType<Type5>, t6: ArgType<Type6>, t7: ArgType<Type7>, t8: ArgType<Type8>, t9: ArgType<Type9>): ArgType<Type1 | Type2 | Type3 | Type4 | Type5 | Type6 | Type7 | Type8 | Type9>; | ||
export function alt(...xs: (Route<object> | ArgType<any>)[]): Route<object> | ArgType<any> { | ||
return (xs as Route<object>[])[0].m ? { | ||
m: path => { | ||
for (let i = 0; i < xs.length; i++) { | ||
const res = (xs as Route<object>[])[i].m(path); | ||
if (is_def(res)) return res; | ||
} | ||
}, | ||
f: args => { | ||
for (let i = 0; i < xs.length; i++) { | ||
const path = (xs as Route<object>[])[i].f(args); | ||
if (is_def(path)) return path; | ||
} | ||
} | ||
} : { | ||
r: new RegExp((xs as ArgType<any>[]).map(({ r }: ArgType<any>) => unwrapRe(r).source).join('|')), | ||
p: v => { | ||
for (let i = 0; i < xs.length; i++) { | ||
if (is_def(v)) { | ||
const m = (xs as ArgType<any>[])[i].r.exec(v); | ||
if (!is_def(m)) continue; | ||
} | ||
const r = (xs as ArgType<any>[])[i].p(v); | ||
if (r.$) return r; | ||
} | ||
return none(); | ||
}, | ||
b: v => { | ||
for (let i = 0; i < xs.length; i++) { | ||
const r = (xs as ArgType<any>[])[i].b(v); | ||
if (is_def(r)) return r; | ||
} | ||
} | ||
}; | ||
} | ||
export function seq<Args1, Args2>(r1: Route<Args1>, r2: Route<Args2>): Route<Args1 & Args2>; | ||
export function seq<Args1, Args2, Args3>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>): Route<Args1 & Args2 & Args3>; | ||
export function seq<Args1, Args2, Args3, Args4>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>): Route<Args1 & Args2 & Args3 & Args4>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>): Route<Args1 & Args2 & Args3 & Args4 & Args5>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15>; | ||
export function seq<Args1, Args2, Args3, Args4, Args5, Args6, Args7, Args8, Args9, Args10, Args11, Args12, Args13, Args14, Args15, Args16>(r1: Route<Args1>, r2: Route<Args2>, r3: Route<Args3>, r4: Route<Args4>, r5: Route<Args5>, r6: Route<Args6>, r7: Route<Args7>, r8: Route<Args8>, r9: Route<Args9>, r10: Route<Args10>, r11: Route<Args11>, r12: Route<Args12>, r13: Route<Args13>, r14: Route<Args14>, r15: Route<Args15>, r16: Route<Args16>): Route<Args1 & Args2 & Args3 & Args4 & Args5 & Args6 & Args7 & Args8 & Args9 & Args10 & Args11 & Args12 & Args13 & Args14 & Args15 & Args16>; | ||
export function seq(...rs: Route<object>[]): Route<object> { | ||
return { | ||
parse: path => { | ||
m: path => { | ||
let args = {}; | ||
for (let i = 0; i < rs.length; i++) { | ||
const res = rs[i].parse(path); | ||
if (res === undefined) return; | ||
const res = rs[i].m(path); | ||
if (!is_def(res)) return; | ||
args = { ...args, ...res[0] }; | ||
@@ -148,7 +247,7 @@ path = res[1]; | ||
}, | ||
build: args => { | ||
f: args => { | ||
let path = ''; | ||
for (let i = 0; i < rs.length; i++) { | ||
const part = rs[i].build(args); | ||
if (part === undefined) return; | ||
const part = rs[i].f(args); | ||
if (!is_def(part)) return; | ||
path += part; | ||
@@ -161,6 +260,8 @@ } | ||
export function router_match<State>(routes: Routes<State>, path: string): Partial<State> | void { | ||
// Router | ||
export function matchs<State>(routes: Routes<State>, path: string): Partial<State> | void { | ||
let state: Partial<State> | void; | ||
for (const id in routes) { | ||
const args = route_match(routes[id], path); | ||
const args = match(routes[id], path); | ||
if (args) { | ||
@@ -174,7 +275,7 @@ if (!state) state = {} as State; | ||
export function router_build<State>(routes: Routes<State>, state: Partial<State>): string | void { | ||
export function builds<State>(routes: Routes<State>, state: Partial<State>): string | void { | ||
for (const id in state) { | ||
const args = state[id]; | ||
if (args !== undefined) { | ||
return route_build(routes[id], args as State[keyof State]); | ||
if (is_def(args)) { | ||
return build(routes[id], args as State[keyof State]); | ||
} | ||
@@ -184,29 +285,24 @@ } | ||
export interface BaseTypes { | ||
str: string; | ||
num: number; | ||
} | ||
// Basic types | ||
export const baseTypes: TypeApi<BaseTypes> = { | ||
str: { | ||
parse: path => { | ||
const m = path.match(/^([^\/\?]+)(.*)$/); | ||
if (m) return [decodeURIComponent(m[1]), m[2]]; | ||
}, | ||
build: arg => typeof arg == 'string' ? encodeURIComponent(arg) : undefined | ||
}, | ||
num: { | ||
parse: path => { | ||
const m = path.match(/^(\-?\d+(?:\.\d+)?)(.*)$/); | ||
if (m) return [parseFloat(m[1]), m[2]]; | ||
}, | ||
build: arg => typeof arg == 'number' ? `${arg}` : undefined, | ||
} | ||
export const str: ArgType<string> = { | ||
r: /^[^\/\?]+/, | ||
p: v => is_def(v) ? some(decodeURIComponent(v)) : none(), | ||
b: v => typeof v == 'string' ? encodeURIComponent(v) : un_def, | ||
}; | ||
export interface NumTypes { | ||
nat: number; | ||
int: number; | ||
} | ||
export const num: ArgType<number> = { | ||
r: /^\-?\d+(?:\.\d+)?/, | ||
p: v => is_def(v) ? some(parseFloat(v)) : none(), | ||
b: v => typeof v ? `${arg}` : un_def, | ||
}; | ||
export const und: ArgType<void> = { | ||
r: /^/, | ||
p: () => some(un_def), | ||
b: () => '' | ||
}; | ||
// Numeric types | ||
function is_int(arg: any): boolean { | ||
@@ -216,17 +312,43 @@ return typeof arg == 'number' && isFinite(arg) && !(arg % 1); | ||
export const numTypes: TypeApi<NumTypes> = { | ||
int: { | ||
parse: path => { | ||
const m = path.match(/^(\-?\d+)(.*)$/); | ||
if (m) return [parseInt(m[1]), m[2]]; | ||
}, | ||
build: arg => is_int(arg) ? `${arg}` : undefined | ||
}, | ||
nat: { | ||
parse: path => { | ||
const m = path.match(/^(\d+)(.*)$/); | ||
if (m) return [parseInt(m[1]), m[2]]; | ||
}, | ||
build: arg => is_int(arg) && arg >= 0 ? `${arg}` : undefined | ||
} | ||
export const int: ArgType<number> = { | ||
r: /^\-?\d+/, | ||
p: v => is_def(v) ? some(parseInt(v)) : none(), | ||
b: v => is_int(v) ? `${v}` : un_def | ||
}; | ||
export const nat: ArgType<number> = { | ||
r: /^\d+/, | ||
p: v => is_def(v) ? some(parseInt(v)) : none(), | ||
b: v => is_int(v) && v >= 0 ? `${v}` : un_def | ||
}; | ||
// Type modifiers | ||
export function opt<Type>({ r, p, b }: ArgType<Type>): ArgType<Type | void> { | ||
return { | ||
r, | ||
p: v => is_def(v) ? p(v) : some(un_def), | ||
b: v => is_def(v) ? b(v) : un_def, | ||
}; | ||
} | ||
export function def<Type>({ r, p, b }: ArgType<Type>, d: Type): ArgType<Type> { | ||
return { | ||
r, | ||
p: v => is_def(v) ? p(v) : some(d), | ||
b: v => v !== d ? b(v) : un_def, | ||
}; | ||
} | ||
interface RegExpData { | ||
source: string, | ||
flags: string, | ||
} | ||
const unwrapRe: (regexp: RegExp) => RegExpData = 'flags' in RegExp.prototype ? | ||
(regexp: RegExp) => regexp : (regexp: RegExp) => { | ||
const strexp = regexp.toString(); | ||
const flags = (/[gimuy]*$/.exec(strexp) as RegExpExecArray)[0]; | ||
const source = strexp.substring(1, strexp.length - 1 - flags.length); | ||
return { source, flags }; | ||
}; |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
89910
1105
209
2
1
+ Addedliterium-base@^0.2.0
+ Addedliterium-base@0.2.4(transitive)