react-routes-forge 1.4.1 → 1.4.2
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/README.md +67 -15
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -22,11 +22,14 @@
|
|
|
22
22
|
- [API reference](#api-reference)
|
|
23
23
|
- [`defineRoutes(routeMap)`](#defineroutesroutemap)
|
|
24
24
|
- [`build(template, params, query?, options?)`](#buildtemplate-params-query-options)
|
|
25
|
+
- [`buildPath(template, params, query?, options?)`](#buildpathtemplate-params-query-options)
|
|
25
26
|
- [`isActivePath(currentPath, template, options?)`](#isactivepathcurrentpath-template-options)
|
|
26
27
|
- [`extractParamsFromPath(template, resolvedPath)`](#extractparamsfrompathtemplate-resolvedpath)
|
|
27
28
|
- [`matchPath(template, options?)`](#matchpathtemplate-options)
|
|
28
29
|
- [`joinPaths(...segments)`](#joinpathssegments)
|
|
29
30
|
- [`getParamNames(template)`](#getparamnamestemplate)
|
|
31
|
+
- [`extractParamNames(template)`](#extractparamnamestemplate)
|
|
32
|
+
- [`isDynamic(template)`](#isdynamictemplate)
|
|
30
33
|
- [`flattenRoutes(routes)`](#flattenroutesroutes)
|
|
31
34
|
- [`getBreadcrumbs(routes, currentPath, options?)`](#getbreadcrumbsroutes-currentpath-options)
|
|
32
35
|
- [`appendQuery(path, query?, hash?)`](#appendquerypath-query-hash)
|
|
@@ -165,13 +168,13 @@ That's the entire API surface you need for most apps. Everything below covers th
|
|
|
165
168
|
|
|
166
169
|
### Route types
|
|
167
170
|
|
|
168
|
-
| Route type | Example | Behaves as
|
|
169
|
-
| ----------- | ----------------------- |
|
|
170
|
-
| **Static** | `HOME: '/'` |
|
|
171
|
-
| **Dynamic** | `DETAILS: '/users/:id'` |
|
|
172
|
-
| **Splat** | `FILES: '/files/*'` |
|
|
171
|
+
| Route type | Example | Behaves as | Gains |
|
|
172
|
+
| ----------- | ----------------------- | ------------------------------------- | --------------------------------------------------------------------- |
|
|
173
|
+
| **Static** | `HOME: '/'` | A primitive string (its template) | `.build(query?, options?)` — attach query/hash, no params to fill |
|
|
174
|
+
| **Dynamic** | `DETAILS: '/users/:id'` | A primitive string (its template) | `.build(params, query?, options?)` and `.paramNames` |
|
|
175
|
+
| **Splat** | `FILES: '/files/*'` | A primitive string (its template) | `.build(params, query?, options?)` and `.paramNames` |
|
|
173
176
|
|
|
174
|
-
`defineRoutes()` walks your route object recursively,
|
|
177
|
+
`defineRoutes()` walks your route object recursively, returning every path as a genuine primitive string. `.build()` (and `.paramNames` on dynamic paths) are attached to `String.prototype` once, so both static and dynamic routes can carry a query string or hash. Dynamic paths (containing a `:param` segment or a trailing `/*` splat) additionally gain `.paramNames`.
|
|
175
178
|
|
|
176
179
|
Param names are `[A-Za-z0-9_]` only (matching React Router), so a static suffix after a param stays literal — `/files/:name.json` builds `{ name: "report" }` → `/files/report.json`, and `:name.json` is **not** treated as a single param name.
|
|
177
180
|
|
|
@@ -197,11 +200,14 @@ Quick reference for everything the package exports — grouped by kind. Click th
|
|
|
197
200
|
| Export | Purpose |
|
|
198
201
|
| ---------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
199
202
|
| [`build(template, params, query?, options?)`](#buildtemplate-params-query-options) | Resolve a template into a URL without `defineRoutes` |
|
|
203
|
+
| [`buildPath(template, params, query?, options?)`](#buildpathtemplate-params-query-options) | Same as `build()` — the underlying resolver `build` aliases |
|
|
200
204
|
| [`isActivePath(currentPath, template, options?)`](#isactivepathcurrentpath-template-options) | Check if a path matches a template (nav-highlighting) |
|
|
201
205
|
| [`extractParamsFromPath(template, resolvedPath)`](#extractparamsfrompathtemplate-resolvedpath) | Pull param values back out of a resolved URL |
|
|
202
206
|
| [`matchPath(template, options?)`](#matchpathtemplate-options) | Convert a route template into an anchored `RegExp` |
|
|
203
207
|
| [`joinPaths(...segments)`](#joinpathssegments) | Join and normalize path segments |
|
|
204
208
|
| [`getParamNames(template)`](#getparamnamestemplate) | List the `:param` names in a template |
|
|
209
|
+
| [`extractParamNames(template)`](#extractparamnamestemplate) | Same as `getParamNames()` — the canonical implementation |
|
|
210
|
+
| [`isDynamic(template)`](#isdynamictemplate) | `true` if a template contains a `:param` or trailing `/*` |
|
|
205
211
|
| [`flattenRoutes(routes)`](#flattenroutesroutes) | Flatten a `PATHS` tree for sitemaps / duplicate detection |
|
|
206
212
|
| [`getBreadcrumbs(routes, currentPath, options?)`](#getbreadcrumbsroutes-currentpath-options) | Build a breadcrumb trail from a route tree and current URL |
|
|
207
213
|
| [`appendQuery(path, query?, hash?)`](#appendquerypath-query-hash) | Append query params / hash to an existing path |
|
|
@@ -227,7 +233,7 @@ Quick reference for everything the package exports — grouped by kind. Click th
|
|
|
227
233
|
|
|
228
234
|
Creates a fully typed route object from a nested plain object.
|
|
229
235
|
|
|
230
|
-
- Every path is string
|
|
236
|
+
- Every path is a genuine primitive string — use it directly anywhere a string is expected (e.g. `<Route path={...} />`).
|
|
231
237
|
- Static paths gain **`.build(query?, options?)`** — attach a query string and/or hash fragment without params.
|
|
232
238
|
- Dynamic paths (containing `:param`) and splat paths (trailing `/*`) gain:
|
|
233
239
|
- **`.build(params, query?, options?)`** — resolves the template into a concrete URL
|
|
@@ -304,6 +310,21 @@ See [Splat (`/*`) segments](#splat--segments) for details.
|
|
|
304
310
|
|
|
305
311
|
---
|
|
306
312
|
|
|
313
|
+
### `buildPath(template, params, query?, options?)`
|
|
314
|
+
|
|
315
|
+
The canonical path resolver that [`build()`](#buildtemplate-params-query-options) is an alias of — identical signature and behaviour. It is exported under both names; reach for `buildPath` when you want the name to match the internals (e.g. when reading the [`useResolvedPath()`](#useresolvedpathtemplate-params-query-options) wrapper), and `build` for a shorter call site.
|
|
316
|
+
|
|
317
|
+
```ts
|
|
318
|
+
import { buildPath } from "react-routes-forge";
|
|
319
|
+
|
|
320
|
+
buildPath("/users/:id", { id: 42 }); // → '/users/42'
|
|
321
|
+
buildPath("/users", {}, { sort: "asc" }); // → '/users?sort=asc'
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
All `build()` examples above apply verbatim to `buildPath`.
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
307
328
|
### `isActivePath(currentPath, template, options?)`
|
|
308
329
|
|
|
309
330
|
Checks whether a resolved path matches a route template — the building block for nav-highlighting ("is this link active?"). Query strings on `currentPath` are ignored automatically. It mirrors React Router's `NavLink` matching semantics:
|
|
@@ -411,6 +432,36 @@ getParamNames("/users"); // → []
|
|
|
411
432
|
|
|
412
433
|
---
|
|
413
434
|
|
|
435
|
+
### `extractParamNames(template)`
|
|
436
|
+
|
|
437
|
+
The canonical implementation behind [`getParamNames()`](#getparamnamestemplate) — same signature and results, kept under both names for compatibility. Param names are `[A-Za-z0-9_]` only, recognized at the start of a segment; a trailing `/*` splat is reported as `['*']`.
|
|
438
|
+
|
|
439
|
+
```ts
|
|
440
|
+
import { extractParamNames } from "react-routes-forge";
|
|
441
|
+
|
|
442
|
+
extractParamNames("/users/:id/posts/:postId"); // → ['id', 'postId']
|
|
443
|
+
extractParamNames("/files/*"); // → ['*']
|
|
444
|
+
extractParamNames("/users"); // → []
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
---
|
|
448
|
+
|
|
449
|
+
### `isDynamic(template)`
|
|
450
|
+
|
|
451
|
+
Returns `true` when a template contains a `:param` segment or a trailing `/*` splat, and `false` otherwise. This is exactly the test `defineRoutes()` uses to decide whether a path gains `.paramNames`:
|
|
452
|
+
|
|
453
|
+
```ts
|
|
454
|
+
import { isDynamic } from "react-routes-forge";
|
|
455
|
+
|
|
456
|
+
isDynamic("/users/:id"); // true
|
|
457
|
+
isDynamic("/users/:id?"); // true (optional params count)
|
|
458
|
+
isDynamic("/files/*"); // true (splat)
|
|
459
|
+
isDynamic("/users"); // false
|
|
460
|
+
isDynamic("/users/foo:bar"); // false (literal colon inside a segment)
|
|
461
|
+
```
|
|
462
|
+
|
|
463
|
+
---
|
|
464
|
+
|
|
414
465
|
### `flattenRoutes(routes)`
|
|
415
466
|
|
|
416
467
|
Walks a `defineRoutes()` tree and returns a flat array of `{ key, path }` entries, where `key` is the dot-joined path from the root (e.g. `"SERVICES.BENEFICIARY_CARE_CENTER.EDIT"`) and `path` is the raw template string.
|
|
@@ -930,22 +981,23 @@ Everywhere the template string itself was used (e.g. `<Route path={PATHS.SERVICE
|
|
|
930
981
|
|
|
931
982
|
## Known behaviours & gotchas
|
|
932
983
|
|
|
933
|
-
### Routes are
|
|
984
|
+
### Routes are genuine primitive strings
|
|
934
985
|
|
|
935
|
-
`defineRoutes`
|
|
986
|
+
`defineRoutes()` returns **plain primitive strings** — `typeof` a route value is `"string"` and strict equality against the template works. `.build()` (and `.paramNames` on dynamic routes) are not own properties of the route value; they are attached to `String.prototype` once, so every route value can still call them lazily from its own text:
|
|
936
987
|
|
|
937
988
|
```ts
|
|
938
989
|
// ✓ These all work as expected
|
|
990
|
+
PATHS.HOME === "/"; // true (strict equality works)
|
|
991
|
+
typeof PATHS.HOME; // 'string'
|
|
939
992
|
String(PATHS.HOME); // '/'
|
|
940
993
|
`${PATHS.USERS.EDIT}`; // '/users/edit/:id'
|
|
941
|
-
PATHS.USERS.EDIT
|
|
942
|
-
|
|
943
|
-
// ✗ Watch out for these
|
|
944
|
-
typeof PATHS.HOME; // 'object' ← not 'string'
|
|
945
|
-
PATHS.HOME === "/"; // false ← strict equality fails
|
|
994
|
+
PATHS.USERS.EDIT.build({ id: 42 }); // '/users/42' (via String.prototype)
|
|
995
|
+
PATHS.USERS.EDIT.paramNames; // ['id']
|
|
946
996
|
```
|
|
947
997
|
|
|
948
|
-
|
|
998
|
+
Because route values are primitives, they work anywhere a plain string does — as object/`Map` keys, and directly with React Router's `<Link to={...}>` or `navigate()` (which branch on `typeof to === "string"`), no `.build()` call required for static paths.
|
|
999
|
+
|
|
1000
|
+
The flip side: since `.build` and `.paramNames` live on `String.prototype`, **every** string in your app has them, not just routes. `"/foo".build({})` → `'/foo'`, and `"/a/:b".paramNames` → `['b']` — `.paramNames` is a lazy getter that parses the string's own text, so it's always correct. Just be aware the helpers exist globally when you're using the library.
|
|
949
1001
|
|
|
950
1002
|
### `useResolvedPath` vs. the library's own `buildPath`
|
|
951
1003
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-routes-forge",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.2",
|
|
4
4
|
"description": "Type-safe route definitions, automatic path builders, query parameter handling, and active route matching for React applications with zero duplication.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": {
|