UNPKG

md-toy-blog

Version:

Very simple Markdown blog: serves your md as html without fancy databases. You will only spend time writing the actual data.

153 lines (124 loc) 4.94 kB
type Partial<T> = { [P in keyof T]?: T[P]; }; type AppConfig = { compiledUserContentDir: string; missingRefValueReplacement: string, mdBlogPostsDir: string; packageName: string; previewLength: number; staticFilesDir: string; pagesDir: string; viewTemplatesDir: string; userCustomConfigPath: string; userProjectRootDir: string; }; type AppConfigFactoryParams = AppConfig & { userCustomConfig: Partial<AppConfig>; }; type RequireOnlyOne<T, Keys extends keyof T = keyof T> = Pick<T, Exclude<keyof T, Keys>> & { [K in Keys]-?: Required<Pick<T, K>> & Partial<Record<Exclude<Keys, K>, undefined>> }[Keys] // Internal Placeholders type ActionParamsDefaultRetType = {}; type RouteConfigDefaultAdditionalPropsType = {}; type RouteUserConfigDefaultAdditionalPropsType = {}; type RouteCtorConfigDefaultAdditionalPropsType = {}; type GetControllerActionParamsMethod<T={}> = (props: { request: HttpRequest; }) => T; type RouteInterface<A=undefined, U={}> = U & CanResolveRouteInterface & { controller: RouteControllerCtorConfig<A>; getControllerActionParams?: GetControllerActionParamsMethod }; // We need two things: // 1. A config generated by user passed to DI to create the route // > ...UserConfig // 2. A config used by Di to pass to the route constructor // > ...CtorConfig // We need two more things: // a. Path // b. RegExp type DiNamedConfig = { name: string; }; type AsInstanceConfig<I> = { instance: I; }; type RouteControllerTypeBothConfig = DiNamedConfig | AsInstanceConfig<ControllerInterface>; type ActionParamsObjectType<A> = { actionParams?: A; actionParamsGetter?: (props: { request: HttpRequest; }) => A; } type RouteControllerWithActionParamsConfig<A=ActionParamsDefaultRetType> = RequireOnlyOne<ActionParamsObjectType<A>, 'actionParams' | 'actionParamsGetter'> type RouteControllerGenericConfig<T extends RouteControllerTypeBothConfig, A=ActionParamsDefaultRetType> = T & RouteControllerWithActionParamsConfig<A>; type RouteControllerUserConfig<A=ActionParamsDefaultRetType> = RouteControllerGenericConfig<RouteControllerTypeBothConfig, A>; type RouteControllerCtorConfig<A=ActionParamsDefaultRetType> = RouteControllerGenericConfig<AsInstanceConfig<ControllerInterface>, A>; // 1. ...UserConfig type RouteUserConfig<E=RouteUserConfigDefaultAdditionalPropsType, A=ActionParamsDefaultRetType> = AsInstanceConfig<RouteInterface<A>> | (E & DiNamedConfig & { controller: RouteControllerUserConfig<A>; }); // 2. ...CtorConfig type RouteCtorConfig<E=RouteCtorConfigDefaultAdditionalPropsType, A=ActionParamsDefaultRetType> = E & { controller: RouteControllerCtorConfig<A>; }; // Our 4 things // F : Further props passed to route First level config // A : ActionParams object type RouteMatchPathUserConfig<F=RouteConfigDefaultAdditionalPropsType, A=ActionParamsDefaultRetType> = RouteUserConfig<F & { path: string; }, A>; type RouteMatchRegExpUserConfig<F=RouteConfigDefaultAdditionalPropsType, A=ActionParamsDefaultRetType> = RouteUserConfig<F & { pathRegExp: RegExp; }, A>; type RouteMatchPathCtorConfig<F=RouteConfigDefaultAdditionalPropsType, A=ActionParamsDefaultRetType> = RouteCtorConfig<F & { paths: string[]; }, A>; type RouteMatchRegExpCtorConfig<F=RouteConfigDefaultAdditionalPropsType, A=ActionParamsDefaultRetType> = RouteCtorConfig<F & { pathRegExp: RegExp; }, A>; type ValidPostSlugListGetterConf = { validPostSlugListGetter: () => string[]; } type StaticFilePathListGetterConf = { staticFilePathListGetter: () => string[]; } interface HttpRequest { url: string; method: 'GET' | 'POST'; } interface IsValidRequestInterface { isValid: (request: HttpRequest) => boolean; } interface MatchesRequestRegExpInterface { matches: (request: HttpRequest, pathRegExp: RegExp) => boolean; } interface MatchesRequestPathInterface { matches: (request: HttpRequest, path: string) => boolean; } interface CanResolveRouteInterface { canResolve: (request: HttpRequest) => boolean; } type RegExpRouteSpecConfig<C=any> = RouteMatchRegExpConfig & MaybeDiControllerConfig<C>; type RegExpRouteConstructorConfig<C=any> = RouteMatchRegExpConfig & RouteConstructorControllerConfig<C>; interface RegExpRouteValidatorConstructorInterface<T> { new (config: RegExpRouteConstructorConfig): RouteInterface<T>; } type PathRouteSpecConfig<C=any> = RouteMatchPathConfig & MaybeDiControllerConfig<C>; type PathRouteConstructorConfig<C=any> = RouteMatchPathConfig & RouteConstructorControllerConfig<C>; interface PathRouteValidatorConstructorInterface<T> { new (config: PathRouteConstructorConfig): RouteInterface<T>; } interface ResponseInterface { code: number; headers: { [k: string]: string; }; body: string; } interface ControllerConstructor { new (config: any): ControllerInterface; } interface ControllerInterface<A={}> { action: (params: A) => Promise<ResponseInterface>; }