@hyeonqyu/typed-router-next 1.4.2 → 1.5.1

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,3 +1,4 @@
1
+ import * as packages_core_dist_routes_types_C0cWyXOZ from 'packages/core/dist/routes.types-C0cWyXOZ';
1
2
  import * as _hyeonqyu_typed_router_core from '@hyeonqyu/typed-router-core';
2
3
  import { SearchParamsForPath, BaseMetadata, PartialRouteTree, RouteTree, ResolvedRouteTree, RouteNode, RoutePathname } from '@hyeonqyu/typed-router-core';
3
4
  export * from '@hyeonqyu/typed-router-core';
@@ -43,11 +44,13 @@ declare const createAppRoutes: <TMetadata extends BaseMetadata, TContext>() => <
43
44
  onError?: "throw" | "default" | "raw";
44
45
  }) => _hyeonqyu_typed_router_core.ExtractSearchParams<_hyeonqyu_typed_router_core.GetRouteNode<TRouteTree, T>>;
45
46
  getCurrentRouteNode: (pathname: RoutePathname<TMetadata, TContext, TRouteTree>) => RouteNode<TMetadata, TContext>;
47
+ getPathnameFromNode: (targetNode: packages_core_dist_routes_types_C0cWyXOZ.R<TMetadata, TContext>, params?: packages_core_dist_routes_types_C0cWyXOZ.S) => string | undefined;
46
48
  appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree, TRouteTree>;
47
49
  _types: {
48
50
  AppRoutesPathname: RoutePathname<TMetadata, TContext, TRouteTree>;
49
51
  AppRoutesMetadata: TMetadata;
50
52
  AppRoutesContext: TContext;
53
+ AppRouteNode: packages_core_dist_routes_types_C0cWyXOZ.R<TMetadata, TContext>;
51
54
  };
52
55
  };
53
56
 
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import * as packages_core_dist_routes_types_C0cWyXOZ from 'packages/core/dist/routes.types-C0cWyXOZ';
1
2
  import * as _hyeonqyu_typed_router_core from '@hyeonqyu/typed-router-core';
2
3
  import { SearchParamsForPath, BaseMetadata, PartialRouteTree, RouteTree, ResolvedRouteTree, RouteNode, RoutePathname } from '@hyeonqyu/typed-router-core';
3
4
  export * from '@hyeonqyu/typed-router-core';
@@ -43,11 +44,13 @@ declare const createAppRoutes: <TMetadata extends BaseMetadata, TContext>() => <
43
44
  onError?: "throw" | "default" | "raw";
44
45
  }) => _hyeonqyu_typed_router_core.ExtractSearchParams<_hyeonqyu_typed_router_core.GetRouteNode<TRouteTree, T>>;
45
46
  getCurrentRouteNode: (pathname: RoutePathname<TMetadata, TContext, TRouteTree>) => RouteNode<TMetadata, TContext>;
47
+ getPathnameFromNode: (targetNode: packages_core_dist_routes_types_C0cWyXOZ.R<TMetadata, TContext>, params?: packages_core_dist_routes_types_C0cWyXOZ.S) => string | undefined;
46
48
  appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree, TRouteTree>;
47
49
  _types: {
48
50
  AppRoutesPathname: RoutePathname<TMetadata, TContext, TRouteTree>;
49
51
  AppRoutesMetadata: TMetadata;
50
52
  AppRoutesContext: TContext;
53
+ AppRouteNode: packages_core_dist_routes_types_C0cWyXOZ.R<TMetadata, TContext>;
51
54
  };
52
55
  };
53
56
 
package/dist/index.js CHANGED
@@ -65,7 +65,7 @@ var createTypedLink = /* @__PURE__ */ __name(() => {
65
65
  }, "createTypedLink");
66
66
  var createAppRoutes = /* @__PURE__ */ __name(() => {
67
67
  return (appRoutes) => {
68
- const { AppRoutesProvider, useAppRoutes, _types } = routes_utils.createAppRoutes()(appRoutes);
68
+ const { AppRoutesProvider, useAppRoutes, getPathnameFromNode, _types } = routes_utils.createAppRoutes()(appRoutes);
69
69
  const TypedLink = createTypedLink();
70
70
  const useTypedRouter = createTypedRouter();
71
71
  const useTypedPathname = createTypedPathname();
@@ -86,6 +86,7 @@ var createAppRoutes = /* @__PURE__ */ __name(() => {
86
86
  useTypedPathname,
87
87
  useTypedSearchParams,
88
88
  getCurrentRouteNode,
89
+ getPathnameFromNode,
89
90
  appRoutes,
90
91
  _types: {
91
92
  ..._types,
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 RouteNode,\n type BaseMetadata,\n type PartialRouteTree,\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, _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 RouteNode<TMetadata, TContext>;\n };\n\n const useCurrentRouteNode = () => {\n const pathname = useTypedPathname();\n return getCurrentRouteNode(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"]}
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 RouteNode,\n type BaseMetadata,\n type PartialRouteTree,\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, getPathnameFromNode, _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 RouteNode<TMetadata, TContext>;\n };\n\n const useCurrentRouteNode = () => {\n const pathname = useTypedPathname();\n return getCurrentRouteNode(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 getPathnameFromNode,\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\n"]}
package/dist/index.mjs CHANGED
@@ -60,7 +60,7 @@ var createTypedLink = /* @__PURE__ */ __name(() => {
60
60
  }, "createTypedLink");
61
61
  var createAppRoutes = /* @__PURE__ */ __name(() => {
62
62
  return (appRoutes) => {
63
- const { AppRoutesProvider, useAppRoutes, _types } = createAppRoutes$1()(appRoutes);
63
+ const { AppRoutesProvider, useAppRoutes, getPathnameFromNode, _types } = createAppRoutes$1()(appRoutes);
64
64
  const TypedLink = createTypedLink();
65
65
  const useTypedRouter = createTypedRouter();
66
66
  const useTypedPathname = createTypedPathname();
@@ -81,6 +81,7 @@ var createAppRoutes = /* @__PURE__ */ __name(() => {
81
81
  useTypedPathname,
82
82
  useTypedSearchParams,
83
83
  getCurrentRouteNode,
84
+ getPathnameFromNode,
84
85
  appRoutes,
85
86
  _types: {
86
87
  ..._types,
@@ -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":";;;;;;;;;;AAEO,IAAM,sCAAsB,MAAA,CAAA,MAAyC;AAC1E,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,WAAW,WAAA,EAAY;AAC7B,IAAA,OAAO,QAAA;AAAA,EACT,CAAA;AACF,CAAA,EALmC,qBAAA,CAAA;ACQ5B,IAAM,oCAAoB,MAAA,CAAA,MAA+D;AAC9F,EAAA,MAAM,uBAAA,mBAA0B,MAAA,CAAA,CAAC,IAAA,EAAiB,YAAA,KAAgC;AAChF,IAAA,OAAO,CAAA,EAAG,IAAI,CAAA,EAAG,oBAAA,CAAqB,YAAA,IAAgB,EAAC,EAAG,EAAE,mBAAA,EAAqB,IAAA,EAAM,CAAC,CAAA,CAAA;AAAA,EAC1F,CAAA,EAFgC,yBAAA,CAAA;AAIhC,EAAA,OAAO,MAAM;AACX,IAAA,MAAM,SAAS,SAAA,EAAU;AAEzB,IAAA,OAAO;AAAA,MACL,MAAM,MAAA,CAAO,IAAA;AAAA,MACb,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,SAAS,MAAA,CAAO,OAAA;AAAA,MAChB,IAAA,kBAAM,MAAA,CAAA,CAA0B,IAAA,EAAa,OAAA,KAAsE;AACjH,QAAA,OAAO,OAAO,IAAA,CAAK,uBAAA,CAAwB,MAAM,OAAA,EAAS,YAA4B,GAAG,OAAO,CAAA;AAAA,MAClG,CAAA,EAFM,MAAA,CAAA;AAAA,MAGN,OAAA,kBAAS,MAAA,CAAA,CAA0B,IAAA,EAAa,OAAA,KAAsE;AACpH,QAAA,OAAO,OAAO,OAAA,CAAQ,uBAAA,CAAwB,MAAM,OAAA,EAAS,YAA4B,GAAG,OAAO,CAAA;AAAA,MACrG,CAAA,EAFS,SAAA,CAAA;AAAA,MAGT,QAAA,kBAAU,MAAA,CAAA,CAA0B,IAAA,EAAa,OAAA,KAAsE;AACrH,QAAA,OAAO,OAAO,QAAA,CAAS,uBAAA,CAAwB,IAAA,EAAM,OAAA,EAAS,YAA4B,CAAC,CAAA;AAAA,MAC7F,CAAA,EAFU,UAAA;AAAA,KAGZ;AAAA,EACF,CAAA;AACF,CAAA,EAvBiC,mBAAA,CAAA;ACG1B,IAAM,0CAA0B,MAAA,CAAA,MAA+D;AACpG,EAAA,OAAO,CAAsB,WAAc,QAAA,KAA4B;AACrE,IAAA,MAAM,eAAe,eAAA,EAAgB;AAKrC,IAAA,MAAM,YAAqC,EAAC;AAC5C,IAAA,YAAA,CAAa,OAAA,CAAQ,CAAC,KAAA,EAAO,GAAA,KAAQ;AACnC,MAAA,MAAM,QAAA,GAAW,UAAU,GAAG,CAAA;AAC9B,MAAA,IAAI,aAAa,MAAA,EAAW;AAE1B,QAAA,SAAA,CAAU,GAAG,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,GAAI,CAAC,GAAG,QAAA,EAAU,KAAK,CAAA,GAAI,CAAC,UAAU,KAAK,CAAA;AAAA,MACpF,CAAA,MAAO;AACL,QAAA,SAAA,CAAU,GAAG,CAAA,GAAI,KAAA;AAAA,MACnB;AAAA,IACF,CAAC,CAAA;AAID,IAAA,OAAO,SAAA;AAAA,EACT,CAAA;AACF,CAAA,EAtBuC,yBAAA,CAAA;ACMhC,IAAM,kCAAkB,MAAA,CAAA,MAA+D;AAC5F,EAAA,MAAM,SAAA,GAAY,UAAA,CAA6E,CAAC,KAAA,EAAO,GAAA,KAAQ;AAC7G,IAAA,uBAAO,GAAA,CAAC,IAAA,EAAA,EAAK,GAAA,EAAW,GAAI,KAAA,EAAyB,CAAA;AAAA,EACvD,CAAC,CAAA;AAED,EAAA,SAAA,CAAU,WAAA,GAAc,WAAA;AAExB,EAAA,OAAO,SAAA;AACT,CAAA,EAR+B,iBAAA,CAAA;ACJxB,IAAM,kCAAkB,MAAA,CAAA,MAAgD;AAC7E,EAAA,OAAO,CAA2D,SAAA,KAAuE;AACvI,IAAA,MAAM,EAAE,iBAAA,EAAmB,YAAA,EAAc,QAAO,GAAIA,iBAAA,GAA2C,SAAS,CAAA;AAKxG,IAAA,MAAM,YAAY,eAAA,EAAsC;AACxD,IAAA,MAAM,iBAAiB,iBAAA,EAAwC;AAC/D,IAAA,MAAM,mBAAmB,mBAAA,EAA8B;AACvD,IAAA,MAAM,uBAAuB,uBAAA,EAA8C;AAE3E,IAAA,MAAM,mBAAA,2BAAuB,QAAA,KAAuB;AAClD,MAAA,OAAO,SAAA,CAAU,GAAA,EAAK,SAAA,EAAW,QAAQ,CAAA;AAAA,IAC3C,CAAA,EAF4B,qBAAA,CAAA;AAI5B,IAAA,MAAM,sCAAsB,MAAA,CAAA,MAAM;AAChC,MAAA,MAAM,WAAW,gBAAA,EAAiB;AAClC,MAAA,OAAO,oBAAoB,QAAQ,CAAA;AAAA,IACrC,CAAA,EAH4B,qBAAA,CAAA;AAK5B,IAAA,OAAO;AAAA,MACL,iBAAA;AAAA,MACA,YAAA;AAAA,MACA,mBAAA;AAAA,MACA,SAAA;AAAA,MACA,cAAA;AAAA,MACA,gBAAA;AAAA,MACA,oBAAA;AAAA,MACA,mBAAA;AAAA,MACA,SAAA;AAAA,MACA,MAAA,EAAQ;AAAA,QACN,GAAG,MAAA;AAAA,QACH,mBAAmB;AAAC;AACtB,KACF;AAAA,EACF,CAAA;AACF,CAAA,EArC+B,iBAAA","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 RouteNode,\n type BaseMetadata,\n type PartialRouteTree,\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, _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 RouteNode<TMetadata, TContext>;\n };\n\n const useCurrentRouteNode = () => {\n const pathname = useTypedPathname();\n return getCurrentRouteNode(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"]}
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 RouteNode,\n type BaseMetadata,\n type PartialRouteTree,\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, getPathnameFromNode, _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 RouteNode<TMetadata, TContext>;\n };\n\n const useCurrentRouteNode = () => {\n const pathname = useTypedPathname();\n return getCurrentRouteNode(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 getPathnameFromNode,\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\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyeonqyu/typed-router-next",
3
- "version": "1.4.2",
3
+ "version": "1.5.1",
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.4.2"
53
+ "@hyeonqyu/typed-router-core": "^1.5.1"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/react": "^19.2.5",