Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

trying out createRoute with component context in 2nd argument #418

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
184 changes: 29 additions & 155 deletions src/services/createRoute.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,173 +6,47 @@ import { CombineQuery } from '@/services/combineQuery'
import { CombineState } from '@/services/combineState'
import { createRouteId } from '@/services/createRouteId'
import { host } from '@/services/host'
import { CreateRouteOptions, WithComponent, WithComponents, WithParent, WithoutComponents, WithoutParent, combineRoutes, isWithParent } from '@/types/createRouteOptions'
import { CreateRouteOptions, ComponentContext, WithParent, WithoutParent, combineRoutes, isWithParent } from '@/types/createRouteOptions'
import { toHash, ToHash } from '@/types/hash'
import { Host } from '@/types/host'
import { toName, ToName } from '@/types/name'
import { ToPath, toPath } from '@/types/path'
import { ToQuery, toQuery } from '@/types/query'
import { Route, ToMeta, ToState } from '@/types/route'
import { CreatedRouteOptions, Route, ToMeta, ToState } from '@/types/route'
import { checkDuplicateParams } from '@/utilities/checkDuplicateKeys'

export function createRoute<
const TOptions
>(options: TOptions & CreateRouteOptions & WithoutComponents & WithoutParent):
TOptions extends CreateRouteOptions
? Route<
ToName<TOptions['name']>,
Host<'', {}>,
ToPath<TOptions['path']>,
ToQuery<TOptions['query']>,
ToHash<TOptions['hash']>,
ToMeta<TOptions['meta']>,
ToState<TOptions['state']>,
[TOptions & { id: string }]
>
: Route<
ToName<undefined>,
Host<'', {}>,
ToPath<undefined>,
ToQuery<undefined>,
ToHash<undefined>,
ToMeta<undefined>,
ToState<undefined>,
[TOptions & { id: string }]
>
const TOptions extends CreateRouteOptions,
const TComponentContext extends Component | ComponentContext<TOptions> | ComponentContext<TOptions>[]
>(options: TOptions & WithoutParent, componentContext?: TComponentContext):
Route<
ToName<TOptions['name']>,
Host<'', {}>,
ToPath<TOptions['path']>,
ToQuery<TOptions['query']>,
ToHash<TOptions['hash']>,
ToMeta<TOptions['meta']>,
ToState<TOptions['state']>,
[CreatedRouteOptions<TOptions, TComponentContext>]
>

export function createRoute<
const TOptions,
const TParent extends Route
>(options: TOptions & CreateRouteOptions & WithoutComponents & WithParent<TParent>):
TOptions extends CreateRouteOptions
? Route<
ToName<TOptions['name']>,
Host<'', {}>,
CombinePath<TParent['path'], ToPath<TOptions['path']>>,
CombineQuery<TParent['query'], ToQuery<TOptions['query']>>,
CombineHash<TParent['hash'], ToHash<TOptions['hash']>>,
CombineMeta<ToMeta<TOptions['meta']>, TParent['meta']>,
CombineState<ToState<TOptions['state']>, TParent['state']>,
[...TParent['matches'], TOptions & { id: string }]
>
: Route<
TParent['name'],
Host<'', {}>,
TParent['path'],
TParent['query'],
TParent['hash'],
TParent['meta'],
TParent['state'],
[TOptions & { id: string }]
>

export function createRoute<
const TOptions,
TComponent extends Component
>(options: TOptions & CreateRouteOptions & WithoutParent & WithComponent<TComponent>):
TOptions extends CreateRouteOptions
? Route<
ToName<TOptions['name']>,
Host<'', {}>,
ToPath<TOptions['path']>,
ToQuery<TOptions['query']>,
ToHash<TOptions['hash']>,
ToMeta<TOptions['meta']>,
ToState<TOptions['state']>,
[TOptions & { id: string }]
>
: Route<
ToName<undefined>,
Host<'', {}>,
ToPath<undefined>,
ToQuery<undefined>,
ToHash<undefined>,
ToMeta<undefined>,
ToState<undefined>,
[TOptions & { id: string }]
>

export function createRoute<
const TOptions,
const TParent extends Route,
const TComponent extends Component
>(options: TOptions & CreateRouteOptions & WithComponent<TComponent> & WithParent<TParent>):
TOptions extends CreateRouteOptions
? Route<
ToName<TOptions['name']>,
Host<'', {}>,
CombinePath<TParent['path'], ToPath<TOptions['path']>>,
CombineQuery<TParent['query'], ToQuery<TOptions['query']>>,
CombineHash<TParent['hash'], ToHash<TOptions['hash']>>,
CombineMeta<ToMeta<TOptions['meta']>, TParent['meta']>,
CombineState<ToState<TOptions['state']>, TParent['state']>,
[...TParent['matches'], TOptions & { id: string }]
>
: Route<
TParent['name'],
Host<'', {}>,
TParent['path'],
TParent['query'],
TParent['hash'],
TParent['meta'],
TParent['state'],
[TOptions & { id: string }]
>

export function createRoute<
const TOptions,
const TComponents extends Record<string, Component>
>(options: TOptions & CreateRouteOptions & WithComponents<TComponents> & WithoutParent):
TOptions extends CreateRouteOptions
? Route<
ToName<TOptions['name']>,
Host<'', {}>,
ToPath<TOptions['path']>,
ToQuery<TOptions['query']>,
ToHash<TOptions['hash']>,
ToMeta<TOptions['meta']>,
ToState<TOptions['state']>,
[TOptions & { id: string }]
>
: Route<
ToName<undefined>,
Host<'', {}>,
ToPath<undefined>,
ToQuery<undefined>,
ToHash<undefined>,
ToMeta<undefined>,
ToState<undefined>,
[TOptions & { id: string }]
>

export function createRoute<
const TOptions,
const TParent extends Route,
const TComponents extends Record<string, Component>
>(options: TOptions & CreateRouteOptions & WithComponents<TComponents> & WithParent<TParent>):
TOptions extends CreateRouteOptions
? Route<
ToName<TOptions['name']>,
Host<'', {}>,
CombinePath<TParent['path'], ToPath<TOptions['path']>>,
CombineQuery<TParent['query'], ToQuery<TOptions['query']>>,
CombineHash<TParent['hash'], ToHash<TOptions['hash']>>,
CombineMeta<ToMeta<TOptions['meta']>, TParent['meta']>,
CombineState<ToState<TOptions['state']>, TParent['state']>,
[...TParent['matches'], TOptions & { id: string }]
>
: Route<
TParent['name'],
Host<'', {}>,
TParent['path'],
TParent['query'],
TParent['hash'],
TParent['meta'],
TParent['state'],
[TOptions & { id: string }]
>
const TOptions extends CreateRouteOptions,
const TComponentContext extends Component | ComponentContext<TOptions> | ComponentContext<TOptions>[]
>(options: TOptions & WithParent<TParent>, componentContext?: TComponentContext):
Route<
ToName<TOptions['name']>,
Host<'', {}>,
CombinePath<TParent['path'], ToPath<TOptions['path']>>,
CombineQuery<TParent['query'], ToQuery<TOptions['query']>>,
CombineHash<TParent['hash'], ToHash<TOptions['hash']>>,
CombineMeta<ToMeta<TOptions['meta']>, TParent['meta']>,
CombineState<ToState<TOptions['state']>, TParent['state']>,
[...TParent['matches'], CreatedRouteOptions<TOptions, TComponentContext>]
>

export function createRoute(options: CreateRouteOptions): Route {
export function createRoute(options: CreateRouteOptions, componentContext?: Component | ComponentContext | ComponentContext[]): Route {
const id = createRouteId()
const name = toName(options.name)
const path = toPath(options.path)
Expand Down
40 changes: 11 additions & 29 deletions src/types/createRouteOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { Query } from '@/types/query'
import { RouteMeta } from '@/types/register'
import { Route } from '@/types/route'
import { MaybePromise } from '@/types/utilities'
import { ResolvedRoute } from '@/types/resolved'
import { PropsCallbackContext } from '@/types/props'
import { WithHooks } from '@/types/hooks'

Expand Down Expand Up @@ -45,40 +44,15 @@ export type WithoutParent = {
parent?: never,
}

export type WithComponent<
export type ComponentContext<
TRoute extends CreateRouteOptions = CreateRouteOptions,
TComponent extends Component = Component
> = {
/**
* A Vue component, which can be either synchronous or asynchronous components.
*/
component: TComponent,
props?: (route: ResolvedRoute, context: PropsCallbackContext) => MaybePromise<ComponentProps<TComponent>>,
}

export function isWithComponent(options: CreateRouteOptions): options is CreateRouteOptions & WithComponent {
return 'component' in options && Boolean(options.component)
}

export type WithComponents<
TComponents extends Record<string, Component> = Record<string, Component>
> = {
/**
* Multiple components for named views, which can be either synchronous or asynchronous components.
*/
components: TComponents,
props?: {
[TKey in keyof TComponents]?: (route: ResolvedRoute, context: PropsCallbackContext) => TComponents[TKey] extends Component ? MaybePromise<ComponentProps<TComponents[TKey]>> : {}
},
}

export type WithoutComponents = {
component?: never,
components?: never,
props?: never,
}

export function isWithComponents(options: CreateRouteOptions): options is CreateRouteOptions & WithComponents {
return 'components' in options && Boolean(options.components)
props?: (route: TRoute, context: PropsCallbackContext) => MaybePromise<ComponentProps<TComponent>>,
}

export type CreateRouteOptions = {
Expand Down Expand Up @@ -110,6 +84,14 @@ export type CreateRouteOptions = {
* Type params for additional data intended to be stored in history state, all keys will be optional unless a default is provided.
*/
state?: Record<string, Param>,
/**
* This property is moved to the `ComponentContext` (2nd argument of `createRoute`).
*/
component?: never,
/**
* This property is moved to the `ComponentContext` (2nd argument of `createRoute`).
*/
components?: never,
}
& WithHooks

Expand Down
13 changes: 7 additions & 6 deletions src/types/route.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { CreateRouteOptions } from '@/types/createRouteOptions'
import { ComponentContext, CreateRouteOptions } from '@/types/createRouteOptions'
import { Hash } from '@/types/hash'
import { Host } from '@/types/host'
import { Param } from '@/types/paramTypes'
import { Path } from '@/types/path'
import { PrefetchConfig } from '@/types/prefetch'
import { Query } from '@/types/query'
import { RouteMeta } from '@/types/register'
import { Component } from 'vue'
import { LastInArray } from './utilities'
import { Component } from 'vue'

/**
* Represents an immutable array of Route instances. Return value of `createRoute`, expected param for `createRouter`.
Expand All @@ -17,11 +17,12 @@ export type Routes = readonly Route[]
export type ToMeta<TMeta extends RouteMeta | undefined> = TMeta extends undefined ? {} : unknown extends TMeta ? {} : TMeta
export type ToState<TState extends Record<string, Param> | undefined> = TState extends undefined ? Record<string, Param> : unknown extends TState ? {} : TState

export type CreatedRouteOptions = CreateRouteOptions & {
export type CreatedRouteOptions<
TOptions extends CreateRouteOptions = CreateRouteOptions,
TComponentContext extends Component | ComponentContext<TOptions> | ComponentContext<TOptions>[] = Component | ComponentContext<TOptions> | ComponentContext<TOptions>[]
> = TOptions & {
id: string,
component?: Component,
components?: Record<string, Component>,
}
} & Component | ComponentContext<TOptions> | ComponentContext<TOptions>[] extends TComponentContext ? {} : TComponentContext

/**
* Represents the structure of a route within the application. Return value of `createRoute`
Expand Down
Loading