@hyeonqyu/typed-router-core 0.2.10 → 1.0.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,13 +1,13 @@
1
- import { P as Paths, a as PathValue } from './routes.types-DTVRnV6j.mjs';
2
- export { B as BaseMetadata, c as PartialRouteTree, f as ResolvedRouteTree, R as RouteNode, b as RouteNodeMetadata, e as RoutePathname, d as RouteTree, S as SimplifyPathname } from './routes.types-DTVRnV6j.mjs';
1
+ import { P as Paths, a as PathValue } from './routes.types-C4Wr8tbE.mjs';
2
+ export { A as AnyZodSchema, B as BaseMetadata, E as ExtractSearchParams, G as GetRouteNode, c as PartialRouteTree, f as ResolvedRouteTree, R as RouteNode, b as RouteNodeMetadata, e as RoutePathname, d as RouteTree, g as SearchParamsForPath, S as SimplifyPathname } from './routes.types-C4Wr8tbE.mjs';
3
3
 
4
- type QueryValue = string | number | boolean | readonly (string | number | boolean)[];
5
- type QueryParams = Record<string, QueryValue>;
4
+ type SearchParamsValue = string | number | boolean | readonly (string | number | boolean)[];
5
+ type SearchParams = Record<string, SearchParamsValue>;
6
6
 
7
7
  declare const getSafely: <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(splitter: TSplitter, obj: TObject, path: TPath) => PathValue<TObject, TPath, TSplitter>;
8
- type QueryStringOptions = {
8
+ type SearchParamsStringOptions = {
9
9
  includeQuestionMark?: boolean;
10
10
  };
11
- declare const toQueryString: (query: QueryParams, options?: QueryStringOptions) => string;
11
+ declare const toSearchParamsString: (searchParams: SearchParams, options?: SearchParamsStringOptions) => string;
12
12
 
13
- export { PathValue, Paths, type QueryParams, type QueryStringOptions, type QueryValue, getSafely, toQueryString };
13
+ export { PathValue, Paths, type SearchParams, type SearchParamsStringOptions, type SearchParamsValue, getSafely, toSearchParamsString };
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { P as Paths, a as PathValue } from './routes.types-DTVRnV6j.js';
2
- export { B as BaseMetadata, c as PartialRouteTree, f as ResolvedRouteTree, R as RouteNode, b as RouteNodeMetadata, e as RoutePathname, d as RouteTree, S as SimplifyPathname } from './routes.types-DTVRnV6j.js';
1
+ import { P as Paths, a as PathValue } from './routes.types-C4Wr8tbE.js';
2
+ export { A as AnyZodSchema, B as BaseMetadata, E as ExtractSearchParams, G as GetRouteNode, c as PartialRouteTree, f as ResolvedRouteTree, R as RouteNode, b as RouteNodeMetadata, e as RoutePathname, d as RouteTree, g as SearchParamsForPath, S as SimplifyPathname } from './routes.types-C4Wr8tbE.js';
3
3
 
4
- type QueryValue = string | number | boolean | readonly (string | number | boolean)[];
5
- type QueryParams = Record<string, QueryValue>;
4
+ type SearchParamsValue = string | number | boolean | readonly (string | number | boolean)[];
5
+ type SearchParams = Record<string, SearchParamsValue>;
6
6
 
7
7
  declare const getSafely: <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(splitter: TSplitter, obj: TObject, path: TPath) => PathValue<TObject, TPath, TSplitter>;
8
- type QueryStringOptions = {
8
+ type SearchParamsStringOptions = {
9
9
  includeQuestionMark?: boolean;
10
10
  };
11
- declare const toQueryString: (query: QueryParams, options?: QueryStringOptions) => string;
11
+ declare const toSearchParamsString: (searchParams: SearchParams, options?: SearchParamsStringOptions) => string;
12
12
 
13
- export { PathValue, Paths, type QueryParams, type QueryStringOptions, type QueryValue, getSafely, toQueryString };
13
+ export { PathValue, Paths, type SearchParams, type SearchParamsStringOptions, type SearchParamsValue, getSafely, toSearchParamsString };
package/dist/index.js CHANGED
@@ -17,9 +17,9 @@ var getSafely = /* @__PURE__ */ __name((splitter, obj, path) => {
17
17
  }
18
18
  return value;
19
19
  }, "getSafely");
20
- var toQueryString = /* @__PURE__ */ __name((query, options = { includeQuestionMark: true }) => {
20
+ var toSearchParamsString = /* @__PURE__ */ __name((searchParams, options = { includeQuestionMark: true }) => {
21
21
  const params = [];
22
- Object.entries(query).forEach(([key, value]) => {
22
+ Object.entries(searchParams).forEach(([key, value]) => {
23
23
  if (value === void 0 || value === null) {
24
24
  return;
25
25
  }
@@ -37,11 +37,11 @@ var toQueryString = /* @__PURE__ */ __name((query, options = { includeQuestionMa
37
37
  if (params.length === 0) {
38
38
  return "";
39
39
  }
40
- const queryString = params.join("&");
41
- return options.includeQuestionMark ? `?${queryString}` : queryString;
42
- }, "toQueryString");
40
+ const searchParamsString = params.join("&");
41
+ return options.includeQuestionMark ? `?${searchParamsString}` : searchParamsString;
42
+ }, "toSearchParamsString");
43
43
 
44
44
  exports.getSafely = getSafely;
45
- exports.toQueryString = toQueryString;
45
+ exports.toSearchParamsString = toSearchParamsString;
46
46
  //# sourceMappingURL=index.js.map
47
47
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/object.utils.ts"],"names":[],"mappings":";;;;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA;AAyBlB,IAAM,gCAAgB,MAAA,CAAA,CAAC,KAAA,EAAoB,UAA8B,EAAE,mBAAA,EAAqB,MAAK,KAAc;AACxH,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAC9C,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,mBAAmB,GAAG,CAAA;AAEzC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,UAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,IAAI,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,QACjE;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AACnC,EAAA,OAAO,OAAA,CAAQ,mBAAA,GAAsB,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,GAAK,WAAA;AAC3D,CAAA,EA3B6B,eAAA","file":"index.js","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { QueryParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type QueryStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toQueryString = (query: QueryParams, options: QueryStringOptions = { includeQuestionMark: true }): string => {\n const params: string[] = [];\n\n Object.entries(query).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const queryString = params.join('&');\n return options.includeQuestionMark ? `?${queryString}` : queryString;\n};\n"]}
1
+ {"version":3,"sources":["../src/object.utils.ts"],"names":[],"mappings":";;;;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA;AAyBlB,IAAM,uCAAuB,MAAA,CAAA,CAClC,YAAA,EACA,UAAqC,EAAE,mBAAA,EAAqB,MAAK,KACtD;AACX,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,MAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AACrD,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,mBAAmB,GAAG,CAAA;AAEzC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,UAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,IAAI,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,QACjE;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,kBAAA,GAAqB,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAC1C,EAAA,OAAO,OAAA,CAAQ,mBAAA,GAAsB,CAAA,CAAA,EAAI,kBAAkB,CAAA,CAAA,GAAK,kBAAA;AAClE,CAAA,EA9BoC,sBAAA","file":"index.js","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { SearchParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type SearchParamsStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toSearchParamsString = (\n searchParams: SearchParams,\n options: SearchParamsStringOptions = { includeQuestionMark: true },\n): string => {\n const params: string[] = [];\n\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const searchParamsString = params.join('&');\n return options.includeQuestionMark ? `?${searchParamsString}` : searchParamsString;\n};\n"]}
package/dist/index.mjs CHANGED
@@ -15,9 +15,9 @@ var getSafely = /* @__PURE__ */ __name((splitter, obj, path) => {
15
15
  }
16
16
  return value;
17
17
  }, "getSafely");
18
- var toQueryString = /* @__PURE__ */ __name((query, options = { includeQuestionMark: true }) => {
18
+ var toSearchParamsString = /* @__PURE__ */ __name((searchParams, options = { includeQuestionMark: true }) => {
19
19
  const params = [];
20
- Object.entries(query).forEach(([key, value]) => {
20
+ Object.entries(searchParams).forEach(([key, value]) => {
21
21
  if (value === void 0 || value === null) {
22
22
  return;
23
23
  }
@@ -35,10 +35,10 @@ var toQueryString = /* @__PURE__ */ __name((query, options = { includeQuestionMa
35
35
  if (params.length === 0) {
36
36
  return "";
37
37
  }
38
- const queryString = params.join("&");
39
- return options.includeQuestionMark ? `?${queryString}` : queryString;
40
- }, "toQueryString");
38
+ const searchParamsString = params.join("&");
39
+ return options.includeQuestionMark ? `?${searchParamsString}` : searchParamsString;
40
+ }, "toSearchParamsString");
41
41
 
42
- export { getSafely, toQueryString };
42
+ export { getSafely, toSearchParamsString };
43
43
  //# sourceMappingURL=index.mjs.map
44
44
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/object.utils.ts"],"names":[],"mappings":";;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA;AAyBlB,IAAM,gCAAgB,MAAA,CAAA,CAAC,KAAA,EAAoB,UAA8B,EAAE,mBAAA,EAAqB,MAAK,KAAc;AACxH,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AAC9C,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,mBAAmB,GAAG,CAAA;AAEzC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,UAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,IAAI,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,QACjE;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AACnC,EAAA,OAAO,OAAA,CAAQ,mBAAA,GAAsB,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA,GAAK,WAAA;AAC3D,CAAA,EA3B6B,eAAA","file":"index.mjs","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { QueryParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type QueryStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toQueryString = (query: QueryParams, options: QueryStringOptions = { includeQuestionMark: true }): string => {\n const params: string[] = [];\n\n Object.entries(query).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const queryString = params.join('&');\n return options.includeQuestionMark ? `?${queryString}` : queryString;\n};\n"]}
1
+ {"version":3,"sources":["../src/object.utils.ts"],"names":[],"mappings":";;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA;AAyBlB,IAAM,uCAAuB,MAAA,CAAA,CAClC,YAAA,EACA,UAAqC,EAAE,mBAAA,EAAqB,MAAK,KACtD;AACX,EAAA,MAAM,SAAmB,EAAC;AAE1B,EAAA,MAAA,CAAO,OAAA,CAAQ,YAAY,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,GAAA,EAAK,KAAK,CAAA,KAAM;AACrD,IAAA,IAAI,KAAA,KAAU,MAAA,IAAa,KAAA,KAAU,IAAA,EAAM;AACzC,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,UAAA,GAAa,mBAAmB,GAAG,CAAA;AAEzC,IAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACxB,MAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,IAAA,KAAS;AACtB,QAAA,IAAI,IAAA,KAAS,MAAA,IAAa,IAAA,KAAS,IAAA,EAAM;AACvC,UAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,IAAI,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,QACjE;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA,MAAO;AACL,MAAA,MAAA,CAAO,IAAA,CAAK,GAAG,UAAU,CAAA,CAAA,EAAI,mBAAmB,MAAA,CAAO,KAAK,CAAC,CAAC,CAAA,CAAE,CAAA;AAAA,IAClE;AAAA,EACF,CAAC,CAAA;AAED,EAAA,IAAI,MAAA,CAAO,WAAW,CAAA,EAAG;AACvB,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,kBAAA,GAAqB,MAAA,CAAO,IAAA,CAAK,GAAG,CAAA;AAC1C,EAAA,OAAO,OAAA,CAAQ,mBAAA,GAAsB,CAAA,CAAA,EAAI,kBAAkB,CAAA,CAAA,GAAK,kBAAA;AAClE,CAAA,EA9BoC,sBAAA","file":"index.mjs","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { SearchParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type SearchParamsStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toSearchParamsString = (\n searchParams: SearchParams,\n options: SearchParamsStringOptions = { includeQuestionMark: true },\n): string => {\n const params: string[] = [];\n\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const searchParamsString = params.join('&');\n return options.includeQuestionMark ? `?${searchParamsString}` : searchParamsString;\n};\n"]}
@@ -4,6 +4,11 @@ type Paths<TObject, TSplitter extends string, TPrev extends string = '', TMaxDep
4
4
  type PathValue<T, P extends string, S extends string, TMaxDepth extends number = 10, TDepth extends unknown[] = []> = TDepth['length'] extends TMaxDepth ? never : P extends S ? T : P extends `${S}${infer Rest}` ? Rest extends `${infer K}${S}${infer R}` ? K extends keyof T ? PathValue<T[K], `${S}${R}`, S, TMaxDepth, [...TDepth, 1]> : never : Rest extends keyof T ? T[Rest] : never : never;
5
5
 
6
6
  type BaseMetadata = NonNullable<unknown>;
7
+ type AnyZodSchema = {
8
+ _input: any;
9
+ _output: any;
10
+ parse: (data: any) => any;
11
+ };
7
12
  type RouteNode<TMetadata extends BaseMetadata, TContext> = {
8
13
  _metadata: RouteNodeMetadata<TMetadata, TContext>;
9
14
  };
@@ -13,6 +18,7 @@ type RouteNodeMetadata<TMetadata extends BaseMetadata, TContext> = {
13
18
  description?: string;
14
19
  href?: (context: TContext) => string;
15
20
  accessible?: (context: TContext) => boolean;
21
+ searchParamsSchema?: AnyZodSchema;
16
22
  } & TMetadata;
17
23
  type PartialRouteTree<TMetadata extends BaseMetadata, TContext> = {
18
24
  [key: string]: RouteNode<TMetadata, TContext> | PartialRouteTree<TMetadata, TContext>;
@@ -29,5 +35,12 @@ type RouteTreeWithoutMetadata<T> = {
29
35
  type RoutePathname<TMetadata extends BaseMetadata, TContext, TRouteTree extends PartialRouteTree<TMetadata, TContext>> = Paths<RouteTreeWithoutMetadata<TRouteTree>, '/', ''>;
30
36
  type SimplifyPathname<T> = T extends string ? T : never;
31
37
  type ResolvedRouteTree<TMetadata extends BaseMetadata, TContext, TRouteTree extends PartialRouteTree<TMetadata, TContext>> = TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>;
38
+ type ExtractSearchParams<TNode> = TNode extends {
39
+ _metadata: {
40
+ searchParamsSchema: AnyZodSchema;
41
+ };
42
+ } ? TNode['_metadata']['searchParamsSchema']['_output'] : Record<string, unknown>;
43
+ type GetRouteNode<TRouteTree, TPath extends string> = TPath extends `/${infer First}/${infer Rest}` ? First extends keyof TRouteTree ? GetRouteNode<TRouteTree[First], `/${Rest}`> : never : TPath extends `/${infer Key}` ? Key extends keyof TRouteTree ? TRouteTree[Key] : never : TRouteTree;
44
+ type SearchParamsForPath<TRouteTree, TPath extends string> = ExtractSearchParams<GetRouteNode<TRouteTree, TPath>>;
32
45
 
33
- export type { BaseMetadata as B, Paths as P, RouteNode as R, SimplifyPathname as S, PathValue as a, RouteNodeMetadata as b, PartialRouteTree as c, RouteTree as d, RoutePathname as e, ResolvedRouteTree as f };
46
+ export type { AnyZodSchema as A, BaseMetadata as B, ExtractSearchParams as E, GetRouteNode as G, Paths as P, RouteNode as R, SimplifyPathname as S, PathValue as a, RouteNodeMetadata as b, PartialRouteTree as c, RouteTree as d, RoutePathname as e, ResolvedRouteTree as f, SearchParamsForPath as g };
@@ -4,6 +4,11 @@ type Paths<TObject, TSplitter extends string, TPrev extends string = '', TMaxDep
4
4
  type PathValue<T, P extends string, S extends string, TMaxDepth extends number = 10, TDepth extends unknown[] = []> = TDepth['length'] extends TMaxDepth ? never : P extends S ? T : P extends `${S}${infer Rest}` ? Rest extends `${infer K}${S}${infer R}` ? K extends keyof T ? PathValue<T[K], `${S}${R}`, S, TMaxDepth, [...TDepth, 1]> : never : Rest extends keyof T ? T[Rest] : never : never;
5
5
 
6
6
  type BaseMetadata = NonNullable<unknown>;
7
+ type AnyZodSchema = {
8
+ _input: any;
9
+ _output: any;
10
+ parse: (data: any) => any;
11
+ };
7
12
  type RouteNode<TMetadata extends BaseMetadata, TContext> = {
8
13
  _metadata: RouteNodeMetadata<TMetadata, TContext>;
9
14
  };
@@ -13,6 +18,7 @@ type RouteNodeMetadata<TMetadata extends BaseMetadata, TContext> = {
13
18
  description?: string;
14
19
  href?: (context: TContext) => string;
15
20
  accessible?: (context: TContext) => boolean;
21
+ searchParamsSchema?: AnyZodSchema;
16
22
  } & TMetadata;
17
23
  type PartialRouteTree<TMetadata extends BaseMetadata, TContext> = {
18
24
  [key: string]: RouteNode<TMetadata, TContext> | PartialRouteTree<TMetadata, TContext>;
@@ -29,5 +35,12 @@ type RouteTreeWithoutMetadata<T> = {
29
35
  type RoutePathname<TMetadata extends BaseMetadata, TContext, TRouteTree extends PartialRouteTree<TMetadata, TContext>> = Paths<RouteTreeWithoutMetadata<TRouteTree>, '/', ''>;
30
36
  type SimplifyPathname<T> = T extends string ? T : never;
31
37
  type ResolvedRouteTree<TMetadata extends BaseMetadata, TContext, TRouteTree extends PartialRouteTree<TMetadata, TContext>> = TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>;
38
+ type ExtractSearchParams<TNode> = TNode extends {
39
+ _metadata: {
40
+ searchParamsSchema: AnyZodSchema;
41
+ };
42
+ } ? TNode['_metadata']['searchParamsSchema']['_output'] : Record<string, unknown>;
43
+ type GetRouteNode<TRouteTree, TPath extends string> = TPath extends `/${infer First}/${infer Rest}` ? First extends keyof TRouteTree ? GetRouteNode<TRouteTree[First], `/${Rest}`> : never : TPath extends `/${infer Key}` ? Key extends keyof TRouteTree ? TRouteTree[Key] : never : TRouteTree;
44
+ type SearchParamsForPath<TRouteTree, TPath extends string> = ExtractSearchParams<GetRouteNode<TRouteTree, TPath>>;
32
45
 
33
- export type { BaseMetadata as B, Paths as P, RouteNode as R, SimplifyPathname as S, PathValue as a, RouteNodeMetadata as b, PartialRouteTree as c, RouteTree as d, RoutePathname as e, ResolvedRouteTree as f };
46
+ export type { AnyZodSchema as A, BaseMetadata as B, ExtractSearchParams as E, GetRouteNode as G, Paths as P, RouteNode as R, SimplifyPathname as S, PathValue as a, RouteNodeMetadata as b, PartialRouteTree as c, RouteTree as d, RoutePathname as e, ResolvedRouteTree as f, SearchParamsForPath as g };
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { B as BaseMetadata, c as PartialRouteTree, d as RouteTree, f as ResolvedRouteTree, e as RoutePathname, a as PathValue } from './routes.types-DTVRnV6j.mjs';
3
+ import { B as BaseMetadata, c as PartialRouteTree, d as RouteTree, f as ResolvedRouteTree, e as RoutePathname, a as PathValue } from './routes.types-C4Wr8tbE.mjs';
4
4
 
5
5
  declare const createAppRoutes: <TMetadata extends BaseMetadata, TContext>() => <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {
6
6
  AppRoutesProvider: ({ children }: {
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import { ReactNode } from 'react';
3
- import { B as BaseMetadata, c as PartialRouteTree, d as RouteTree, f as ResolvedRouteTree, e as RoutePathname, a as PathValue } from './routes.types-DTVRnV6j.js';
3
+ import { B as BaseMetadata, c as PartialRouteTree, d as RouteTree, f as ResolvedRouteTree, e as RoutePathname, a as PathValue } from './routes.types-C4Wr8tbE.js';
4
4
 
5
5
  declare const createAppRoutes: <TMetadata extends BaseMetadata, TContext>() => <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {
6
6
  AppRoutesProvider: ({ children }: {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/object.utils.ts","../src/routes.utils.tsx"],"names":["createContext","useContext"],"mappings":";;;;;;;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA,CAAA;ACElB,IAAM,eAAA,mBACX,MAAA,CAAA,MACA,CAA2D,SAAA,KAAuE;AAIhI,EAAA,MAAM,OAAA,GAAUA,oBAAsB,SAAmB,CAAA;AAEzD,EAAA,MAAM,+BAAe,MAAA,CAAA,MAAc;AACjC,IAAA,OAAOC,iBAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,EAFqB,cAAA,CAAA;AAIrB,EAAA,MAAM,mBAAA,2BAA+C,QAAA,KAAuD;AAC1G,IAAA,MAAM,MAAA,GAASA,iBAAW,OAAO,CAAA;AACjC,IAAA,OAAO,SAAA,CAAU,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,EACxC,CAAA,EAH4B,qBAAA,CAAA;AAK5B,EAAA,MAAM,iBAAA,mBAAoB,MAAA,CAAA,CAAC,EAAE,QAAA,EAAS,KAA+B;AACnE,IAAA,sCAAQ,OAAA,CAAQ,QAAA,EAAR,EAAiB,KAAA,EAAO,WAAsB,QAAA,EAAS,CAAA;AAAA,EACjE,CAAA,EAF0B,mBAAA,CAAA;AAI1B,EAAA,OAAO;AAAA,IACL,iBAAA;AAAA,IACA,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,QAAQ;AAAC,GAKX;AACF,CAAA,EA9BA,iBAAA","file":"routes.utils.js","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { QueryParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type QueryStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toQueryString = (query: QueryParams, options: QueryStringOptions = { includeQuestionMark: true }): string => {\n const params: string[] = [];\n\n Object.entries(query).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const queryString = params.join('&');\n return options.includeQuestionMark ? `?${queryString}` : queryString;\n};\n","import { createContext, ReactNode, useContext } from 'react';\nimport { getSafely } from './object.utils';\nimport { PathValue } from './path.types';\nimport { BaseMetadata, PartialRouteTree, ResolvedRouteTree, RoutePathname, RouteTree } from './routes.types';\n\nexport const createAppRoutes =\n <TMetadata extends BaseMetadata, TContext>() =>\n <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n\n const Context = createContext<Routes>(appRoutes as Routes);\n\n const useAppRoutes = (): Routes => {\n return useContext(Context);\n };\n\n const useCurrentRouteNode = <TPath extends Pathname>(pathname: TPath): PathValue<TRouteTree, TPath, '/'> => {\n const routes = useContext(Context);\n return getSafely('/', routes, pathname) as PathValue<TRouteTree, TPath, '/'>;\n };\n\n const AppRoutesProvider = ({ children }: { children: ReactNode }) => {\n return <Context.Provider value={appRoutes as Routes}>{children}</Context.Provider>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes,\n useCurrentRouteNode,\n _types: {} as {\n AppRoutesMetadata: TMetadata;\n AppRoutesContext: TContext;\n AppRoutesPathname: Pathname;\n },\n };\n };\n"]}
1
+ {"version":3,"sources":["../src/object.utils.ts","../src/routes.utils.tsx"],"names":["createContext","useContext"],"mappings":";;;;;;;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA,CAAA;ACElB,IAAM,eAAA,mBACX,MAAA,CAAA,MACA,CAA2D,SAAA,KAAuE;AAIhI,EAAA,MAAM,OAAA,GAAUA,oBAAsB,SAAmB,CAAA;AAEzD,EAAA,MAAM,+BAAe,MAAA,CAAA,MAAc;AACjC,IAAA,OAAOC,iBAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,EAFqB,cAAA,CAAA;AAIrB,EAAA,MAAM,mBAAA,2BAA+C,QAAA,KAAuD;AAC1G,IAAA,MAAM,MAAA,GAASA,iBAAW,OAAO,CAAA;AACjC,IAAA,OAAO,SAAA,CAAU,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,EACxC,CAAA,EAH4B,qBAAA,CAAA;AAK5B,EAAA,MAAM,iBAAA,mBAAoB,MAAA,CAAA,CAAC,EAAE,QAAA,EAAS,KAA+B;AACnE,IAAA,sCAAQ,OAAA,CAAQ,QAAA,EAAR,EAAiB,KAAA,EAAO,WAAsB,QAAA,EAAS,CAAA;AAAA,EACjE,CAAA,EAF0B,mBAAA,CAAA;AAI1B,EAAA,OAAO;AAAA,IACL,iBAAA;AAAA,IACA,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,QAAQ;AAAC,GAKX;AACF,CAAA,EA9BA,iBAAA","file":"routes.utils.js","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { SearchParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type SearchParamsStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toSearchParamsString = (\n searchParams: SearchParams,\n options: SearchParamsStringOptions = { includeQuestionMark: true },\n): string => {\n const params: string[] = [];\n\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const searchParamsString = params.join('&');\n return options.includeQuestionMark ? `?${searchParamsString}` : searchParamsString;\n};\n","import { createContext, ReactNode, useContext } from 'react';\nimport { getSafely } from './object.utils';\nimport { PathValue } from './path.types';\nimport { BaseMetadata, PartialRouteTree, ResolvedRouteTree, RoutePathname, RouteTree } from './routes.types';\n\nexport const createAppRoutes =\n <TMetadata extends BaseMetadata, TContext>() =>\n <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n\n const Context = createContext<Routes>(appRoutes as Routes);\n\n const useAppRoutes = (): Routes => {\n return useContext(Context);\n };\n\n const useCurrentRouteNode = <TPath extends Pathname>(pathname: TPath): PathValue<TRouteTree, TPath, '/'> => {\n const routes = useContext(Context);\n return getSafely('/', routes, pathname) as PathValue<TRouteTree, TPath, '/'>;\n };\n\n const AppRoutesProvider = ({ children }: { children: ReactNode }) => {\n return <Context.Provider value={appRoutes as Routes}>{children}</Context.Provider>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes,\n useCurrentRouteNode,\n _types: {} as {\n AppRoutesMetadata: TMetadata;\n AppRoutesContext: TContext;\n AppRoutesPathname: Pathname;\n },\n };\n };\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/object.utils.ts","../src/routes.utils.tsx"],"names":[],"mappings":";;;;;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA,CAAA;ACElB,IAAM,eAAA,mBACX,MAAA,CAAA,MACA,CAA2D,SAAA,KAAuE;AAIhI,EAAA,MAAM,OAAA,GAAU,cAAsB,SAAmB,CAAA;AAEzD,EAAA,MAAM,+BAAe,MAAA,CAAA,MAAc;AACjC,IAAA,OAAO,WAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,EAFqB,cAAA,CAAA;AAIrB,EAAA,MAAM,mBAAA,2BAA+C,QAAA,KAAuD;AAC1G,IAAA,MAAM,MAAA,GAAS,WAAW,OAAO,CAAA;AACjC,IAAA,OAAO,SAAA,CAAU,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,EACxC,CAAA,EAH4B,qBAAA,CAAA;AAK5B,EAAA,MAAM,iBAAA,mBAAoB,MAAA,CAAA,CAAC,EAAE,QAAA,EAAS,KAA+B;AACnE,IAAA,2BAAQ,OAAA,CAAQ,QAAA,EAAR,EAAiB,KAAA,EAAO,WAAsB,QAAA,EAAS,CAAA;AAAA,EACjE,CAAA,EAF0B,mBAAA,CAAA;AAI1B,EAAA,OAAO;AAAA,IACL,iBAAA;AAAA,IACA,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,QAAQ;AAAC,GAKX;AACF,CAAA,EA9BA,iBAAA","file":"routes.utils.mjs","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { QueryParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type QueryStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toQueryString = (query: QueryParams, options: QueryStringOptions = { includeQuestionMark: true }): string => {\n const params: string[] = [];\n\n Object.entries(query).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const queryString = params.join('&');\n return options.includeQuestionMark ? `?${queryString}` : queryString;\n};\n","import { createContext, ReactNode, useContext } from 'react';\nimport { getSafely } from './object.utils';\nimport { PathValue } from './path.types';\nimport { BaseMetadata, PartialRouteTree, ResolvedRouteTree, RoutePathname, RouteTree } from './routes.types';\n\nexport const createAppRoutes =\n <TMetadata extends BaseMetadata, TContext>() =>\n <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n\n const Context = createContext<Routes>(appRoutes as Routes);\n\n const useAppRoutes = (): Routes => {\n return useContext(Context);\n };\n\n const useCurrentRouteNode = <TPath extends Pathname>(pathname: TPath): PathValue<TRouteTree, TPath, '/'> => {\n const routes = useContext(Context);\n return getSafely('/', routes, pathname) as PathValue<TRouteTree, TPath, '/'>;\n };\n\n const AppRoutesProvider = ({ children }: { children: ReactNode }) => {\n return <Context.Provider value={appRoutes as Routes}>{children}</Context.Provider>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes,\n useCurrentRouteNode,\n _types: {} as {\n AppRoutesMetadata: TMetadata;\n AppRoutesContext: TContext;\n AppRoutesPathname: Pathname;\n },\n };\n };\n"]}
1
+ {"version":3,"sources":["../src/object.utils.ts","../src/routes.utils.tsx"],"names":[],"mappings":";;;;;;;AAGO,IAAM,SAAA,mBAAY,MAAA,CAAA,CACvB,QAAA,EACA,GAAA,EACA,IAAA,KACyC;AACzC,EAAA,IAAI,IAAA,KAAS,EAAA,IAAM,IAAA,KAAS,QAAA,EAAU,OAAO,GAAA;AAE7C,EAAA,MAAM,IAAA,GAAQ,IAAA,CAAgB,KAAA,CAAM,QAAQ,CAAA;AAC5C,EAAA,IAAI,KAAA,GAAiB,GAAA;AAErB,EAAA,KAAA,MAAW,OAAO,IAAA,EAAM;AACtB,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,KAAU,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/D,MAAA,KAAA,GAAS,MAAkC,GAAG,CAAA;AAAA,IAChD,CAAA,MAAO;AACL,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAEA,EAAA,OAAO,KAAA;AACT,CAAA,EAnByB,WAAA,CAAA;ACElB,IAAM,eAAA,mBACX,MAAA,CAAA,MACA,CAA2D,SAAA,KAAuE;AAIhI,EAAA,MAAM,OAAA,GAAU,cAAsB,SAAmB,CAAA;AAEzD,EAAA,MAAM,+BAAe,MAAA,CAAA,MAAc;AACjC,IAAA,OAAO,WAAW,OAAO,CAAA;AAAA,EAC3B,CAAA,EAFqB,cAAA,CAAA;AAIrB,EAAA,MAAM,mBAAA,2BAA+C,QAAA,KAAuD;AAC1G,IAAA,MAAM,MAAA,GAAS,WAAW,OAAO,CAAA;AACjC,IAAA,OAAO,SAAA,CAAU,GAAA,EAAK,MAAA,EAAQ,QAAQ,CAAA;AAAA,EACxC,CAAA,EAH4B,qBAAA,CAAA;AAK5B,EAAA,MAAM,iBAAA,mBAAoB,MAAA,CAAA,CAAC,EAAE,QAAA,EAAS,KAA+B;AACnE,IAAA,2BAAQ,OAAA,CAAQ,QAAA,EAAR,EAAiB,KAAA,EAAO,WAAsB,QAAA,EAAS,CAAA;AAAA,EACjE,CAAA,EAF0B,mBAAA,CAAA;AAI1B,EAAA,OAAO;AAAA,IACL,iBAAA;AAAA,IACA,YAAA;AAAA,IACA,mBAAA;AAAA,IACA,QAAQ;AAAC,GAKX;AACF,CAAA,EA9BA,iBAAA","file":"routes.utils.mjs","sourcesContent":["import { Paths, PathValue } from './path.types';\nimport { SearchParams } from './query.types';\n\nexport const getSafely = <TObject, TSplitter extends string, TPath extends string & Paths<TObject, TSplitter>>(\n splitter: TSplitter,\n obj: TObject,\n path: TPath,\n): PathValue<TObject, TPath, TSplitter> => {\n if (path === '' || path === splitter) return obj as PathValue<TObject, TPath, TSplitter>;\n\n const keys = (path as string).split(splitter);\n let value: unknown = obj;\n\n for (const key of keys) {\n if (typeof value === 'object' && value !== null && key in value) {\n value = (value as Record<string, unknown>)[key];\n } else {\n return undefined as PathValue<TObject, TPath, TSplitter>;\n }\n }\n\n return value as PathValue<TObject, TPath, TSplitter>;\n};\n\nexport type SearchParamsStringOptions = {\n includeQuestionMark?: boolean;\n};\n\nexport const toSearchParamsString = (\n searchParams: SearchParams,\n options: SearchParamsStringOptions = { includeQuestionMark: true },\n): string => {\n const params: string[] = [];\n\n Object.entries(searchParams).forEach(([key, value]) => {\n if (value === undefined || value === null) {\n return;\n }\n\n const encodedKey = encodeURIComponent(key);\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n if (item !== undefined && item !== null) {\n params.push(`${encodedKey}=${encodeURIComponent(String(item))}`);\n }\n });\n } else {\n params.push(`${encodedKey}=${encodeURIComponent(String(value))}`);\n }\n });\n\n if (params.length === 0) {\n return '';\n }\n\n const searchParamsString = params.join('&');\n return options.includeQuestionMark ? `?${searchParamsString}` : searchParamsString;\n};\n","import { createContext, ReactNode, useContext } from 'react';\nimport { getSafely } from './object.utils';\nimport { PathValue } from './path.types';\nimport { BaseMetadata, PartialRouteTree, ResolvedRouteTree, RoutePathname, RouteTree } from './routes.types';\n\nexport const createAppRoutes =\n <TMetadata extends BaseMetadata, TContext>() =>\n <TRouteTree extends PartialRouteTree<TMetadata, TContext>>(appRoutes: TRouteTree & RouteTree<TMetadata, TContext, TRouteTree>) => {\n type Routes = ResolvedRouteTree<TMetadata, TContext, TRouteTree>;\n type Pathname = RoutePathname<TMetadata, TContext, TRouteTree>;\n\n const Context = createContext<Routes>(appRoutes as Routes);\n\n const useAppRoutes = (): Routes => {\n return useContext(Context);\n };\n\n const useCurrentRouteNode = <TPath extends Pathname>(pathname: TPath): PathValue<TRouteTree, TPath, '/'> => {\n const routes = useContext(Context);\n return getSafely('/', routes, pathname) as PathValue<TRouteTree, TPath, '/'>;\n };\n\n const AppRoutesProvider = ({ children }: { children: ReactNode }) => {\n return <Context.Provider value={appRoutes as Routes}>{children}</Context.Provider>;\n };\n\n return {\n AppRoutesProvider,\n useAppRoutes,\n useCurrentRouteNode,\n _types: {} as {\n AppRoutesMetadata: TMetadata;\n AppRoutesContext: TContext;\n AppRoutesPathname: Pathname;\n },\n };\n };\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyeonqyu/typed-router-core",
3
- "version": "0.2.10",
3
+ "version": "1.0.1",
4
4
  "description": "Core types and utilities for typed-router",
5
5
  "author": "hyeonQyu <dhk0561@naver.com>",
6
6
  "license": "MIT",
@@ -49,12 +49,19 @@
49
49
  "type": "tsc --noEmit"
50
50
  },
51
51
  "peerDependencies": {
52
- "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
52
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
53
+ "zod": "^3.0.0"
54
+ },
55
+ "peerDependenciesMeta": {
56
+ "zod": {
57
+ "optional": true
58
+ }
53
59
  },
54
60
  "devDependencies": {
55
61
  "@types/react": "^19.2.5",
56
62
  "react": "^19.2.0",
57
- "typescript": "^5.9.3"
63
+ "typescript": "^5.9.3",
64
+ "zod": "^3.24.1"
58
65
  },
59
66
  "engines": {
60
67
  "node": ">=18.0.0"