@hyeonqyu/typed-router-next 1.2.2 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _hyeonqyu_typed_router_core from '@hyeonqyu/typed-router-core';
2
- import { SearchParamsForPath, BaseMetadata, PartialRouteTree, RouteTree, ResolvedRouteTree, RoutePathname, PathValue } from '@hyeonqyu/typed-router-core';
2
+ import { SearchParamsForPath, BaseMetadata, PartialRouteTree, RouteTree, ResolvedRouteTree, PathValue, RoutePathname } from '@hyeonqyu/typed-router-core';
3
3
  export * from '@hyeonqyu/typed-router-core';
4
4
  import * as react from 'react';
5
5
  import { ComponentProps } from 'react';
@@ -20,7 +20,7 @@ declare const createAppRoutes: <TMetadata extends BaseMetadata, TContext>() => <
20
20
  children: react.ReactNode;
21
21
  }) => react_jsx_runtime.JSX.Element;
22
22
  useAppRoutes: () => ResolvedRouteTree<TMetadata, TContext, TRouteTree>;
23
- useCurrentRouteNode: <TPath extends RoutePathname<TMetadata, TContext, TRouteTree>>(pathname: TPath) => PathValue<TRouteTree, TPath, "/">;
23
+ useCurrentRouteNode: () => PathValue<TRouteTree, RoutePathname<TMetadata, TContext, TRouteTree>, "/">;
24
24
  TypedLink: react.ForwardRefExoticComponent<Omit<TypedLinkProps<RoutePathname<TMetadata, TContext, TRouteTree>, TRouteTree>, "ref"> & react.RefAttributes<HTMLAnchorElement>>;
25
25
  useTypedRouter: () => {
26
26
  back: () => void;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as _hyeonqyu_typed_router_core from '@hyeonqyu/typed-router-core';
2
- import { SearchParamsForPath, BaseMetadata, PartialRouteTree, RouteTree, ResolvedRouteTree, RoutePathname, PathValue } from '@hyeonqyu/typed-router-core';
2
+ import { SearchParamsForPath, BaseMetadata, PartialRouteTree, RouteTree, ResolvedRouteTree, PathValue, RoutePathname } from '@hyeonqyu/typed-router-core';
3
3
  export * from '@hyeonqyu/typed-router-core';
4
4
  import * as react from 'react';
5
5
  import { ComponentProps } from 'react';
@@ -20,7 +20,7 @@ declare const createAppRoutes: <TMetadata extends BaseMetadata, TContext>() => <
20
20
  children: react.ReactNode;
21
21
  }) => react_jsx_runtime.JSX.Element;
22
22
  useAppRoutes: () => ResolvedRouteTree<TMetadata, TContext, TRouteTree>;
23
- useCurrentRouteNode: <TPath extends RoutePathname<TMetadata, TContext, TRouteTree>>(pathname: TPath) => PathValue<TRouteTree, TPath, "/">;
23
+ useCurrentRouteNode: () => PathValue<TRouteTree, RoutePathname<TMetadata, TContext, TRouteTree>, "/">;
24
24
  TypedLink: react.ForwardRefExoticComponent<Omit<TypedLinkProps<RoutePathname<TMetadata, TContext, TRouteTree>, TRouteTree>, "ref"> & react.RefAttributes<HTMLAnchorElement>>;
25
25
  useTypedRouter: () => {
26
26
  back: () => void;
package/dist/index.js CHANGED
@@ -65,7 +65,12 @@ var createTypedLink = /* @__PURE__ */ __name(() => {
65
65
  }, "createTypedLink");
66
66
  var createAppRoutes = /* @__PURE__ */ __name(() => {
67
67
  return (appRoutes) => {
68
- const { AppRoutesProvider, useAppRoutes, useCurrentRouteNode, _types } = routes_utils.createAppRoutes()(appRoutes);
68
+ const {
69
+ AppRoutesProvider,
70
+ useAppRoutes,
71
+ useCurrentRouteNode: useCurrentRouteNodeCore,
72
+ _types
73
+ } = routes_utils.createAppRoutes()(appRoutes);
69
74
  const TypedLink = createTypedLink();
70
75
  const useTypedRouter = createTypedRouter();
71
76
  const useTypedPathname = createTypedPathname();
@@ -73,6 +78,10 @@ var createAppRoutes = /* @__PURE__ */ __name(() => {
73
78
  const getCurrentRouteNode = /* @__PURE__ */ __name((pathname) => {
74
79
  return typedRouterCore.getSafely("/", appRoutes, pathname);
75
80
  }, "getCurrentRouteNode");
81
+ const useCurrentRouteNode = /* @__PURE__ */ __name(() => {
82
+ const pathname = useTypedPathname();
83
+ return useCurrentRouteNodeCore(pathname);
84
+ }, "useCurrentRouteNode");
76
85
  return {
77
86
  AppRoutesProvider,
78
87
  useAppRoutes,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pathname.hooks.ts","../src/router.hooks.ts","../src/searchParams.hooks.ts","../src/TypedLink.tsx","../src/index.tsx"],"names":["usePathname","toSearchParamsString","useRouter","useSearchParams","forwardRef","jsx","Link","createAppRoutesCore","getSafely"],"mappings":"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","file":"index.js","sourcesContent":["import { usePathname } from 'next/navigation';\n\nexport const createTypedPathname = <TPathname extends string = string>() => {\n return () => {\n const pathname = usePathname();\n return pathname as TPathname;\n };\n};\n","import { SearchParams, SearchParamsForPath, toSearchParamsString } from '@hyeonqyu/typed-router-core';\nimport { useRouter } from 'next/navigation';\n\ntype NavigateOptions<TSearchParams = SearchParams> = {\n scroll?: boolean;\n searchParams?: TSearchParams;\n};\n\ntype PrefetchOptions<TSearchParams = SearchParams> = Pick<NavigateOptions<TSearchParams>, 'searchParams'>;\n\nexport const createTypedRouter = <TPathname extends string = string, TRouteTree = unknown>() => {\n const getHrefWithSearchParams = (href: TPathname, searchParams?: SearchParams) => {\n return `${href}${toSearchParamsString(searchParams ?? {}, { includeQuestionMark: true })}`;\n };\n\n return () => {\n const router = useRouter();\n\n return {\n back: router.back,\n forward: router.forward,\n refresh: router.refresh,\n push: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.push(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n replace: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.replace(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n prefetch: <TPath extends TPathname>(href: TPath, options?: PrefetchOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.prefetch(getHrefWithSearchParams(href, options?.searchParams as SearchParams));\n },\n };\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport { useSearchParams } from 'next/navigation';\n\ntype ParseOptions = {\n /**\n * Error handling mode\n * - 'throw': Throw error on validation failure\n * - 'default': Return schema defaults on validation failure\n * - 'raw': Return raw unparsed values on validation failure\n */\n onError?: 'throw' | 'default' | 'raw';\n};\n\nexport const createTypedSearchParams = <TPathname extends string = string, TRouteTree = unknown>() => {\n return <T extends TPathname>(_pathname: T, _options?: ParseOptions) => {\n const searchParams = useSearchParams();\n\n type ExpectedParams = SearchParamsForPath<TRouteTree, T>;\n\n // Convert URLSearchParams to plain object\n const rawParams: Record<string, unknown> = {};\n searchParams.forEach((value, key) => {\n const existing = rawParams[key];\n if (existing !== undefined) {\n // Handle multiple values for the same key\n rawParams[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];\n } else {\n rawParams[key] = value;\n }\n });\n\n // For now, return raw params as ExpectedParams\n // When schema is available at runtime, we would parse with Zod here\n return rawParams as ExpectedParams;\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport Link from 'next/link';\nimport type { ComponentProps, ComponentRef } from 'react';\nimport { forwardRef } from 'react';\n\ntype NextLinkProps = ComponentProps<typeof Link>;\n\nexport type TypedLinkProps<TPathname extends string = string, TRouteTree = unknown> = Omit<NextLinkProps, 'href'> & {\n href:\n | TPathname\n | (TPathname extends infer TPath\n ? {\n pathname: TPath;\n searchParams?: SearchParamsForPath<TRouteTree, TPath & string>;\n hash?: string;\n }\n : never);\n};\n\nexport const createTypedLink = <TPathname extends string = string, TRouteTree = unknown>() => {\n const TypedLink = forwardRef<ComponentRef<typeof Link>, TypedLinkProps<TPathname, TRouteTree>>((props, ref) => {\n return <Link ref={ref} {...(props as NextLinkProps)} />;\n });\n\n TypedLink.displayName = 'TypedLink';\n\n return TypedLink;\n};\n","import {\n getSafely,\n type BaseMetadata,\n type PartialRouteTree,\n type PathValue,\n type ResolvedRouteTree,\n type RoutePathname,\n type RouteTree,\n} from '@hyeonqyu/typed-router-core';\nimport { createAppRoutes as createAppRoutesCore } from '@hyeonqyu/typed-router-core/routes.utils';\nimport { createTypedPathname } from './pathname.hooks';\nimport { createTypedRouter } from './router.hooks';\nimport { createTypedSearchParams } from './searchParams.hooks';\nimport { createTypedLink } from './TypedLink';\n\nexport const createAppRoutes = <TMetadata extends BaseMetadata, TContext>() => {\n return <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n const { AppRoutesProvider, useAppRoutes, useCurrentRouteNode, _types } = createAppRoutesCore<TMetadata, TContext>()(appRoutes);\n\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n\n const TypedLink = createTypedLink<Pathname, TRouteTree>();\n const useTypedRouter = createTypedRouter<Pathname, TRouteTree>();\n const useTypedPathname = createTypedPathname<Pathname>();\n const useTypedSearchParams = createTypedSearchParams<Pathname, TRouteTree>();\n\n const getCurrentRouteNode = (pathname: Pathname) => {\n return getSafely('/', appRoutes, pathname) as PathValue<TRouteTree, Pathname, '/'>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes: useAppRoutes as () => Routes,\n useCurrentRouteNode: useCurrentRouteNode as <TPath extends Pathname>(pathname: TPath) => PathValue<TRouteTree, TPath, '/'>,\n TypedLink,\n useTypedRouter,\n useTypedPathname,\n useTypedSearchParams,\n getCurrentRouteNode,\n appRoutes,\n _types: {\n ..._types,\n AppRoutesPathname: {} as Pathname,\n },\n };\n };\n};\n\nexport * from '@hyeonqyu/typed-router-core';\nexport type { TypedLinkProps } from './TypedLink';\n"]}
1
+ {"version":3,"sources":["../src/pathname.hooks.ts","../src/router.hooks.ts","../src/searchParams.hooks.ts","../src/TypedLink.tsx","../src/index.tsx"],"names":["usePathname","toSearchParamsString","useRouter","useSearchParams","forwardRef","jsx","Link","createAppRoutesCore","getSafely"],"mappings":"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","file":"index.js","sourcesContent":["import { usePathname } from 'next/navigation';\n\nexport const createTypedPathname = <TPathname extends string = string>() => {\n return () => {\n const pathname = usePathname();\n return pathname as TPathname;\n };\n};\n","import { SearchParams, SearchParamsForPath, toSearchParamsString } from '@hyeonqyu/typed-router-core';\nimport { useRouter } from 'next/navigation';\n\ntype NavigateOptions<TSearchParams = SearchParams> = {\n scroll?: boolean;\n searchParams?: TSearchParams;\n};\n\ntype PrefetchOptions<TSearchParams = SearchParams> = Pick<NavigateOptions<TSearchParams>, 'searchParams'>;\n\nexport const createTypedRouter = <TPathname extends string = string, TRouteTree = unknown>() => {\n const getHrefWithSearchParams = (href: TPathname, searchParams?: SearchParams) => {\n return `${href}${toSearchParamsString(searchParams ?? {}, { includeQuestionMark: true })}`;\n };\n\n return () => {\n const router = useRouter();\n\n return {\n back: router.back,\n forward: router.forward,\n refresh: router.refresh,\n push: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.push(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n replace: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.replace(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n prefetch: <TPath extends TPathname>(href: TPath, options?: PrefetchOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.prefetch(getHrefWithSearchParams(href, options?.searchParams as SearchParams));\n },\n };\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport { useSearchParams } from 'next/navigation';\n\ntype ParseOptions = {\n /**\n * Error handling mode\n * - 'throw': Throw error on validation failure\n * - 'default': Return schema defaults on validation failure\n * - 'raw': Return raw unparsed values on validation failure\n */\n onError?: 'throw' | 'default' | 'raw';\n};\n\nexport const createTypedSearchParams = <TPathname extends string = string, TRouteTree = unknown>() => {\n return <T extends TPathname>(_pathname: T, _options?: ParseOptions) => {\n const searchParams = useSearchParams();\n\n type ExpectedParams = SearchParamsForPath<TRouteTree, T>;\n\n // Convert URLSearchParams to plain object\n const rawParams: Record<string, unknown> = {};\n searchParams.forEach((value, key) => {\n const existing = rawParams[key];\n if (existing !== undefined) {\n // Handle multiple values for the same key\n rawParams[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];\n } else {\n rawParams[key] = value;\n }\n });\n\n // For now, return raw params as ExpectedParams\n // When schema is available at runtime, we would parse with Zod here\n return rawParams as ExpectedParams;\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport Link from 'next/link';\nimport type { ComponentProps, ComponentRef } from 'react';\nimport { forwardRef } from 'react';\n\ntype NextLinkProps = ComponentProps<typeof Link>;\n\nexport type TypedLinkProps<TPathname extends string = string, TRouteTree = unknown> = Omit<NextLinkProps, 'href'> & {\n href:\n | TPathname\n | (TPathname extends infer TPath\n ? {\n pathname: TPath;\n searchParams?: SearchParamsForPath<TRouteTree, TPath & string>;\n hash?: string;\n }\n : never);\n};\n\nexport const createTypedLink = <TPathname extends string = string, TRouteTree = unknown>() => {\n const TypedLink = forwardRef<ComponentRef<typeof Link>, TypedLinkProps<TPathname, TRouteTree>>((props, ref) => {\n return <Link ref={ref} {...(props as NextLinkProps)} />;\n });\n\n TypedLink.displayName = 'TypedLink';\n\n return TypedLink;\n};\n","import {\n getSafely,\n type BaseMetadata,\n type PartialRouteTree,\n type PathValue,\n type ResolvedRouteTree,\n type RoutePathname,\n type RouteTree,\n} from '@hyeonqyu/typed-router-core';\nimport { createAppRoutes as createAppRoutesCore } from '@hyeonqyu/typed-router-core/routes.utils';\nimport { createTypedPathname } from './pathname.hooks';\nimport { createTypedRouter } from './router.hooks';\nimport { createTypedSearchParams } from './searchParams.hooks';\nimport { createTypedLink } from './TypedLink';\n\nexport const createAppRoutes = <TMetadata extends BaseMetadata, TContext>() => {\n return <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n const {\n AppRoutesProvider,\n useAppRoutes,\n useCurrentRouteNode: useCurrentRouteNodeCore,\n _types,\n } = createAppRoutesCore<TMetadata, TContext>()(appRoutes);\n\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n\n const TypedLink = createTypedLink<Pathname, TRouteTree>();\n const useTypedRouter = createTypedRouter<Pathname, TRouteTree>();\n const useTypedPathname = createTypedPathname<Pathname>();\n const useTypedSearchParams = createTypedSearchParams<Pathname, TRouteTree>();\n\n const getCurrentRouteNode = (pathname: Pathname) => {\n return getSafely('/', appRoutes, pathname) as PathValue<TRouteTree, Pathname, '/'>;\n };\n\n const useCurrentRouteNode = (): PathValue<TRouteTree, Pathname, '/'> => {\n const pathname = useTypedPathname();\n return useCurrentRouteNodeCore(pathname) as PathValue<TRouteTree, Pathname, '/'>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes: useAppRoutes as () => Routes,\n useCurrentRouteNode,\n TypedLink,\n useTypedRouter,\n useTypedPathname,\n useTypedSearchParams,\n getCurrentRouteNode,\n appRoutes,\n _types: {\n ..._types,\n AppRoutesPathname: {} as Pathname,\n },\n };\n };\n};\n\nexport * from '@hyeonqyu/typed-router-core';\nexport type { TypedLinkProps } from './TypedLink';\n"]}
package/dist/index.mjs CHANGED
@@ -60,7 +60,12 @@ var createTypedLink = /* @__PURE__ */ __name(() => {
60
60
  }, "createTypedLink");
61
61
  var createAppRoutes = /* @__PURE__ */ __name(() => {
62
62
  return (appRoutes) => {
63
- const { AppRoutesProvider, useAppRoutes, useCurrentRouteNode, _types } = createAppRoutes$1()(appRoutes);
63
+ const {
64
+ AppRoutesProvider,
65
+ useAppRoutes,
66
+ useCurrentRouteNode: useCurrentRouteNodeCore,
67
+ _types
68
+ } = createAppRoutes$1()(appRoutes);
64
69
  const TypedLink = createTypedLink();
65
70
  const useTypedRouter = createTypedRouter();
66
71
  const useTypedPathname = createTypedPathname();
@@ -68,6 +73,10 @@ var createAppRoutes = /* @__PURE__ */ __name(() => {
68
73
  const getCurrentRouteNode = /* @__PURE__ */ __name((pathname) => {
69
74
  return getSafely("/", appRoutes, pathname);
70
75
  }, "getCurrentRouteNode");
76
+ const useCurrentRouteNode = /* @__PURE__ */ __name(() => {
77
+ const pathname = useTypedPathname();
78
+ return useCurrentRouteNodeCore(pathname);
79
+ }, "useCurrentRouteNode");
71
80
  return {
72
81
  AppRoutesProvider,
73
82
  useAppRoutes,
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/pathname.hooks.ts","../src/router.hooks.ts","../src/searchParams.hooks.ts","../src/TypedLink.tsx","../src/index.tsx"],"names":["createAppRoutesCore"],"mappings":"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","file":"index.mjs","sourcesContent":["import { usePathname } from 'next/navigation';\n\nexport const createTypedPathname = <TPathname extends string = string>() => {\n return () => {\n const pathname = usePathname();\n return pathname as TPathname;\n };\n};\n","import { SearchParams, SearchParamsForPath, toSearchParamsString } from '@hyeonqyu/typed-router-core';\nimport { useRouter } from 'next/navigation';\n\ntype NavigateOptions<TSearchParams = SearchParams> = {\n scroll?: boolean;\n searchParams?: TSearchParams;\n};\n\ntype PrefetchOptions<TSearchParams = SearchParams> = Pick<NavigateOptions<TSearchParams>, 'searchParams'>;\n\nexport const createTypedRouter = <TPathname extends string = string, TRouteTree = unknown>() => {\n const getHrefWithSearchParams = (href: TPathname, searchParams?: SearchParams) => {\n return `${href}${toSearchParamsString(searchParams ?? {}, { includeQuestionMark: true })}`;\n };\n\n return () => {\n const router = useRouter();\n\n return {\n back: router.back,\n forward: router.forward,\n refresh: router.refresh,\n push: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.push(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n replace: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.replace(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n prefetch: <TPath extends TPathname>(href: TPath, options?: PrefetchOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.prefetch(getHrefWithSearchParams(href, options?.searchParams as SearchParams));\n },\n };\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport { useSearchParams } from 'next/navigation';\n\ntype ParseOptions = {\n /**\n * Error handling mode\n * - 'throw': Throw error on validation failure\n * - 'default': Return schema defaults on validation failure\n * - 'raw': Return raw unparsed values on validation failure\n */\n onError?: 'throw' | 'default' | 'raw';\n};\n\nexport const createTypedSearchParams = <TPathname extends string = string, TRouteTree = unknown>() => {\n return <T extends TPathname>(_pathname: T, _options?: ParseOptions) => {\n const searchParams = useSearchParams();\n\n type ExpectedParams = SearchParamsForPath<TRouteTree, T>;\n\n // Convert URLSearchParams to plain object\n const rawParams: Record<string, unknown> = {};\n searchParams.forEach((value, key) => {\n const existing = rawParams[key];\n if (existing !== undefined) {\n // Handle multiple values for the same key\n rawParams[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];\n } else {\n rawParams[key] = value;\n }\n });\n\n // For now, return raw params as ExpectedParams\n // When schema is available at runtime, we would parse with Zod here\n return rawParams as ExpectedParams;\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport Link from 'next/link';\nimport type { ComponentProps, ComponentRef } from 'react';\nimport { forwardRef } from 'react';\n\ntype NextLinkProps = ComponentProps<typeof Link>;\n\nexport type TypedLinkProps<TPathname extends string = string, TRouteTree = unknown> = Omit<NextLinkProps, 'href'> & {\n href:\n | TPathname\n | (TPathname extends infer TPath\n ? {\n pathname: TPath;\n searchParams?: SearchParamsForPath<TRouteTree, TPath & string>;\n hash?: string;\n }\n : never);\n};\n\nexport const createTypedLink = <TPathname extends string = string, TRouteTree = unknown>() => {\n const TypedLink = forwardRef<ComponentRef<typeof Link>, TypedLinkProps<TPathname, TRouteTree>>((props, ref) => {\n return <Link ref={ref} {...(props as NextLinkProps)} />;\n });\n\n TypedLink.displayName = 'TypedLink';\n\n return TypedLink;\n};\n","import {\n getSafely,\n type BaseMetadata,\n type PartialRouteTree,\n type PathValue,\n type ResolvedRouteTree,\n type RoutePathname,\n type RouteTree,\n} from '@hyeonqyu/typed-router-core';\nimport { createAppRoutes as createAppRoutesCore } from '@hyeonqyu/typed-router-core/routes.utils';\nimport { createTypedPathname } from './pathname.hooks';\nimport { createTypedRouter } from './router.hooks';\nimport { createTypedSearchParams } from './searchParams.hooks';\nimport { createTypedLink } from './TypedLink';\n\nexport const createAppRoutes = <TMetadata extends BaseMetadata, TContext>() => {\n return <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n const { AppRoutesProvider, useAppRoutes, useCurrentRouteNode, _types } = createAppRoutesCore<TMetadata, TContext>()(appRoutes);\n\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n\n const TypedLink = createTypedLink<Pathname, TRouteTree>();\n const useTypedRouter = createTypedRouter<Pathname, TRouteTree>();\n const useTypedPathname = createTypedPathname<Pathname>();\n const useTypedSearchParams = createTypedSearchParams<Pathname, TRouteTree>();\n\n const getCurrentRouteNode = (pathname: Pathname) => {\n return getSafely('/', appRoutes, pathname) as PathValue<TRouteTree, Pathname, '/'>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes: useAppRoutes as () => Routes,\n useCurrentRouteNode: useCurrentRouteNode as <TPath extends Pathname>(pathname: TPath) => PathValue<TRouteTree, TPath, '/'>,\n TypedLink,\n useTypedRouter,\n useTypedPathname,\n useTypedSearchParams,\n getCurrentRouteNode,\n appRoutes,\n _types: {\n ..._types,\n AppRoutesPathname: {} as Pathname,\n },\n };\n };\n};\n\nexport * from '@hyeonqyu/typed-router-core';\nexport type { TypedLinkProps } from './TypedLink';\n"]}
1
+ {"version":3,"sources":["../src/pathname.hooks.ts","../src/router.hooks.ts","../src/searchParams.hooks.ts","../src/TypedLink.tsx","../src/index.tsx"],"names":["createAppRoutesCore"],"mappings":"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","file":"index.mjs","sourcesContent":["import { usePathname } from 'next/navigation';\n\nexport const createTypedPathname = <TPathname extends string = string>() => {\n return () => {\n const pathname = usePathname();\n return pathname as TPathname;\n };\n};\n","import { SearchParams, SearchParamsForPath, toSearchParamsString } from '@hyeonqyu/typed-router-core';\nimport { useRouter } from 'next/navigation';\n\ntype NavigateOptions<TSearchParams = SearchParams> = {\n scroll?: boolean;\n searchParams?: TSearchParams;\n};\n\ntype PrefetchOptions<TSearchParams = SearchParams> = Pick<NavigateOptions<TSearchParams>, 'searchParams'>;\n\nexport const createTypedRouter = <TPathname extends string = string, TRouteTree = unknown>() => {\n const getHrefWithSearchParams = (href: TPathname, searchParams?: SearchParams) => {\n return `${href}${toSearchParamsString(searchParams ?? {}, { includeQuestionMark: true })}`;\n };\n\n return () => {\n const router = useRouter();\n\n return {\n back: router.back,\n forward: router.forward,\n refresh: router.refresh,\n push: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.push(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n replace: <TPath extends TPathname>(href: TPath, options?: NavigateOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.replace(getHrefWithSearchParams(href, options?.searchParams as SearchParams), options);\n },\n prefetch: <TPath extends TPathname>(href: TPath, options?: PrefetchOptions<SearchParamsForPath<TRouteTree, TPath>>) => {\n return router.prefetch(getHrefWithSearchParams(href, options?.searchParams as SearchParams));\n },\n };\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport { useSearchParams } from 'next/navigation';\n\ntype ParseOptions = {\n /**\n * Error handling mode\n * - 'throw': Throw error on validation failure\n * - 'default': Return schema defaults on validation failure\n * - 'raw': Return raw unparsed values on validation failure\n */\n onError?: 'throw' | 'default' | 'raw';\n};\n\nexport const createTypedSearchParams = <TPathname extends string = string, TRouteTree = unknown>() => {\n return <T extends TPathname>(_pathname: T, _options?: ParseOptions) => {\n const searchParams = useSearchParams();\n\n type ExpectedParams = SearchParamsForPath<TRouteTree, T>;\n\n // Convert URLSearchParams to plain object\n const rawParams: Record<string, unknown> = {};\n searchParams.forEach((value, key) => {\n const existing = rawParams[key];\n if (existing !== undefined) {\n // Handle multiple values for the same key\n rawParams[key] = Array.isArray(existing) ? [...existing, value] : [existing, value];\n } else {\n rawParams[key] = value;\n }\n });\n\n // For now, return raw params as ExpectedParams\n // When schema is available at runtime, we would parse with Zod here\n return rawParams as ExpectedParams;\n };\n};\n","import type { SearchParamsForPath } from '@hyeonqyu/typed-router-core';\nimport Link from 'next/link';\nimport type { ComponentProps, ComponentRef } from 'react';\nimport { forwardRef } from 'react';\n\ntype NextLinkProps = ComponentProps<typeof Link>;\n\nexport type TypedLinkProps<TPathname extends string = string, TRouteTree = unknown> = Omit<NextLinkProps, 'href'> & {\n href:\n | TPathname\n | (TPathname extends infer TPath\n ? {\n pathname: TPath;\n searchParams?: SearchParamsForPath<TRouteTree, TPath & string>;\n hash?: string;\n }\n : never);\n};\n\nexport const createTypedLink = <TPathname extends string = string, TRouteTree = unknown>() => {\n const TypedLink = forwardRef<ComponentRef<typeof Link>, TypedLinkProps<TPathname, TRouteTree>>((props, ref) => {\n return <Link ref={ref} {...(props as NextLinkProps)} />;\n });\n\n TypedLink.displayName = 'TypedLink';\n\n return TypedLink;\n};\n","import {\n getSafely,\n type BaseMetadata,\n type PartialRouteTree,\n type PathValue,\n type ResolvedRouteTree,\n type RoutePathname,\n type RouteTree,\n} from '@hyeonqyu/typed-router-core';\nimport { createAppRoutes as createAppRoutesCore } from '@hyeonqyu/typed-router-core/routes.utils';\nimport { createTypedPathname } from './pathname.hooks';\nimport { createTypedRouter } from './router.hooks';\nimport { createTypedSearchParams } from './searchParams.hooks';\nimport { createTypedLink } from './TypedLink';\n\nexport const createAppRoutes = <TMetadata extends BaseMetadata, TContext>() => {\n return <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n const {\n AppRoutesProvider,\n useAppRoutes,\n useCurrentRouteNode: useCurrentRouteNodeCore,\n _types,\n } = createAppRoutesCore<TMetadata, TContext>()(appRoutes);\n\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n\n const TypedLink = createTypedLink<Pathname, TRouteTree>();\n const useTypedRouter = createTypedRouter<Pathname, TRouteTree>();\n const useTypedPathname = createTypedPathname<Pathname>();\n const useTypedSearchParams = createTypedSearchParams<Pathname, TRouteTree>();\n\n const getCurrentRouteNode = (pathname: Pathname) => {\n return getSafely('/', appRoutes, pathname) as PathValue<TRouteTree, Pathname, '/'>;\n };\n\n const useCurrentRouteNode = (): PathValue<TRouteTree, Pathname, '/'> => {\n const pathname = useTypedPathname();\n return useCurrentRouteNodeCore(pathname) as PathValue<TRouteTree, Pathname, '/'>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes: useAppRoutes as () => Routes,\n useCurrentRouteNode,\n TypedLink,\n useTypedRouter,\n useTypedPathname,\n useTypedSearchParams,\n getCurrentRouteNode,\n appRoutes,\n _types: {\n ..._types,\n AppRoutesPathname: {} as Pathname,\n },\n };\n };\n};\n\nexport * from '@hyeonqyu/typed-router-core';\nexport type { TypedLinkProps } from './TypedLink';\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyeonqyu/typed-router-next",
3
- "version": "1.2.2",
3
+ "version": "1.3.0",
4
4
  "description": "Type-safe IA-first routing for Next.js",
5
5
  "author": "hyeonQyu <dhk0561@naver.com>",
6
6
  "license": "MIT",
@@ -50,7 +50,7 @@
50
50
  "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
51
51
  },
52
52
  "dependencies": {
53
- "@hyeonqyu/typed-router-core": "^1.2.2"
53
+ "@hyeonqyu/typed-router-core": "^1.3.0"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/react": "^19.2.5",