Skip to content

Commit

Permalink
feat: added typed useLink #120
Browse files Browse the repository at this point in the history
  • Loading branch information
victorgarciaesgi committed Nov 9, 2023
1 parent d39d8ce commit cb94539
Show file tree
Hide file tree
Showing 11 changed files with 330 additions and 11 deletions.
8 changes: 4 additions & 4 deletions playground/src/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,14 @@

<nuxt-link to="/admin/:id?foo">Navigate Link</nuxt-link>

<nuxt-link :to="{ name: '' }">Navigate Link</nuxt-link>
<nuxt-link :to="localePath({ name: '' })">Navigate Link</nuxt-link>
<nuxt-link :to="{ name: 'admin-id', params: { id: 1 } }">Navigate Link</nuxt-link>
<nuxt-link :to="localePath({ name: 'user' })">Navigate Link</nuxt-link>
<nuxt-layout></nuxt-layout>
</div>
</template>

<script setup lang="ts">
import { TypedRouteLocationRawFromName, helpers, TypedRouteLocation } from '@typed-router';
import { Body } from '#components';
import type { TypedRouteLocationRawFromName, helpers, TypedRouteLocation } from '@typed-router';
// definePageMeta({
// redirect: (route) => helpers.route({ name: 'admin-id', params: { id: 1 } }),
// });
Expand Down Expand Up @@ -57,6 +56,7 @@ function navigate() {
const route = localePath(`/user/${u}/:slug/articles`);
router.push('/');
navigateTo('ednzelfjle', { external: true });
const route4 = navigateTo('/test/:foo');
router.push({ path: '/' });
router.push('/user/:id/:slug/articles#baz');
Expand Down
5 changes: 5 additions & 0 deletions src/core/output/fileSave/definitions.save.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
createTypeUtilsRuntimeFile,
createTypedRouterDefinitionFile,
createTypedRouterFile,
createUseTypedLinkFile,
createUseTypedRouteFile,
createUseTypedRouterFile,
createi18nRouterFile,
Expand All @@ -37,6 +38,10 @@ export async function saveGeneratedFiles({ outputData }: SaveGeneratedFiles): Pr
fileName: '__useTypedRoute.ts',
content: createUseTypedRouteFile(),
},
{
fileName: '__useTypedLink.ts',
content: createUseTypedLinkFile(),
},
{
fileName: '__paths.d.ts',
content: createPathsFiles(outputData),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ export function createLocaleRoutePathSchema(routePaths: RoutePathsDecl[]) {

export function createValidatePathTypes(
pathElements: DestructuredPath[][][],
routesList: string[],
withLocale = false
): string {
let pathConditions = pathElements.map(createTypeValidatePathCondition).filter((f) => {
Expand Down Expand Up @@ -61,7 +62,7 @@ export function createValidatePathTypes(
}
: never;
// RouteNameFromPath, RouteNameFromLocalePath
export type RouteNameFrom${returnIfTrue(
withLocale,
'Locale'
Expand All @@ -71,6 +72,7 @@ export function createValidatePathTypes(
${
pathConditions.length
? `: ${pathConditions
.filter((f) => routesList.includes(f.routeName))
.map((t) => `${t.typeName}<T> extends true ? "${t.routeName}"`)
.join(': ')} : never`
: ': never'
Expand Down
3 changes: 2 additions & 1 deletion src/core/output/generators/files/__navigateTo.file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,8 @@ export function createNavigateToFile() {
) : Promise<void | NavigationFailure | TypedRouteFromName<RouteNameFromPath<T>>>`
)}
}
export const navigateTo: NavigateToFunction = defaultNavigateTo as any;
export const navigateTo: NavigateToFunction = defaultNavigateTo as any;
`;
}
6 changes: 3 additions & 3 deletions src/core/output/generators/files/__paths.file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
createValidatePathTypes,
} from '../blocks';

export function createPathsFiles({ routesPaths }: GeneratorOutput) {
export function createPathsFiles({ routesPaths, routesList }: GeneratorOutput) {
const { i18n, i18nOptions } = moduleOptionStore;
const hasPrefixStrategy = i18n && i18nOptions?.strategy !== 'no_prefix';

Expand Down Expand Up @@ -79,8 +79,8 @@ export function createPathsFiles({ routesPaths }: GeneratorOutput) {
})
.filter((f) => f.length);

const validatePathTypes = createValidatePathTypes(pathElements);
const validateLocalePathTypes = createValidatePathTypes(pathElements, true);
const validatePathTypes = createValidatePathTypes(pathElements, routesList);
const validateLocalePathTypes = createValidatePathTypes(pathElements, routesList, true);

return /* typescript */ `
Expand Down
2 changes: 2 additions & 0 deletions src/core/output/generators/files/__typed-router.d.file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export function createTypedRouterDefinitionFile(): string {
import type {TypedRouter, TypedRoute, TypedRouteLocationRawFromName, TypedLocationAsRelativeRaw} from './__router';
import { useRoute as _useRoute } from './__useTypedRoute';
import { useRouter as _useRouter } from './__useTypedRouter';
import { useLink as _useLink } from './__useTypedLink';
import { navigateTo as _navigateTo } from './__navigateTo';
${returnIfTrue(
i18n,
Expand All @@ -32,6 +33,7 @@ export function createTypedRouterDefinitionFile(): string {
/* typescript */ `
const useRoute: typeof _useRoute;
const useRouter: typeof _useRouter;
const useLink: typeof _useLink;
const navigateTo: typeof _navigateTo;
const definePageMeta: typeof _definePageMeta;
Expand Down
63 changes: 63 additions & 0 deletions src/core/output/generators/files/__useTypedLink.file.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { returnIfTrue } from '../../../../utils';
import { moduleOptionStore } from '../../../config';

export function createUseTypedLinkFile(): string {
const strictOptions = moduleOptionStore.getResolvedStrictOptions();
const { pathCheck } = moduleOptionStore;

return /* typescript */ `
import { useLink as defaultLink } from '#imports';
import type {MaybeRef} from 'vue';
import type { NavigateToOptions } from 'nuxt/dist/app/composables/router';
import type { NavigationFailure } from 'vue-router';
import type { TypedRouteLocationRawFromName, TypedRouteFromName, TypedRoute } from './__router';
import type { RoutesNamesList } from './__routes';
${returnIfTrue(
pathCheck,
`import type {TypedPathParameter, RouteNameFromPath} from './__paths';`
)}
type LinkedRoute<T extends RoutesNamesList> = {
route: ComputedRef<TypedRouteFromName<T> & {
href: string;
}>;
href: ComputedRef<string>;
isActive: ComputedRef<boolean>;
isExactActive: ComputedRef<boolean>;
navigate: (e?: MouseEvent) => Promise<void | NavigationFailure>;
};
interface UseLinkFunction {
<T extends RoutesNamesList, P extends string>(
props: {
to: MaybeRef<TypedRouteLocationRawFromName<T, P>>,
replace?: MaybeRef<boolean>
}
) : LinkedRoute<T>
${returnIfTrue(
pathCheck && !strictOptions.router.strictToArgument,
`<T extends string>(
props: {
to: MaybeRef<TypedPathParameter<T>>,
replace?: MaybeRef<boolean>
}
) : LinkedRoute<RouteNameFromPath<T>>`
)}
}
/**
* Typed clone of \`useLink\`
*
* @exemple
*
* \`\`\`ts
* const router = useLink(props);
* \`\`\`
*/
export const useLink: UseLinkFunction = defaultLink as any;
`;
}
1 change: 1 addition & 0 deletions src/core/output/generators/files/index.file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export function createIndexFile(): string {
} from './__routes';
export { useRoute } from './__useTypedRoute';
export { useRouter } from './__useTypedRouter';
export { useLink } from './__useTypedLink';
export { navigateTo } from './__navigateTo';
export { definePageMeta } from './__definePageMeta';
export { helpers } from './__helpers';
Expand Down
1 change: 1 addition & 0 deletions src/core/output/generators/files/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from './index.file';
export * from './plugin.file';
export * from './__useTypedRoute.file';
export * from './__useTypedRouter.file';
export * from './__useTypedLink.file';
export * from './__navigateTo.file';
export * from './__types-utils.d.file';
export * from './__i18n-router.file';
Expand Down
3 changes: 1 addition & 2 deletions test/fixtures/simple/tests/router/navigateTo.spec-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { assertType } from 'vitest';
import { assertType, test } from 'vitest';
import type { LocationQuery } from 'vue-router';
import test from 'node:test';

// ! ------ Should Error ❌

Expand Down

1 comment on commit cb94539

@vercel
Copy link

@vercel vercel bot commented on cb94539 Nov 9, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.