@plumile/router 0.1.11 → 0.1.12
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 +342 -1
- package/lib/esm/builder.d.ts.map +1 -1
- package/lib/esm/builder.js +10 -3
- package/lib/esm/eslint-rules/index.d.ts +2 -0
- package/lib/esm/eslint-rules/index.d.ts.map +1 -0
- package/lib/esm/eslint-rules/index.js +2 -0
- package/lib/esm/eslint-rules/no-direct-window-location-search.d.ts +4 -0
- package/lib/esm/eslint-rules/no-direct-window-location-search.d.ts.map +1 -0
- package/lib/esm/eslint-rules/no-direct-window-location-search.js +48 -0
- package/lib/esm/history/BrowserHistory.d.ts.map +1 -1
- package/lib/esm/history/BrowserHistory.js +4 -2
- package/lib/esm/index.d.ts +1 -0
- package/lib/esm/index.d.ts.map +1 -1
- package/lib/esm/index.js +2 -1
- package/lib/esm/routing/Link.d.ts +1 -0
- package/lib/esm/routing/Link.d.ts.map +1 -1
- package/lib/esm/routing/Link.js +35 -4
- package/lib/esm/routing/RouteComponentWrapper.d.ts.map +1 -1
- package/lib/esm/routing/RouteComponentWrapper.js +7 -2
- package/lib/esm/routing/createRouter.d.ts +7 -1
- package/lib/esm/routing/createRouter.d.ts.map +1 -1
- package/lib/esm/routing/createRouter.js +494 -11
- package/lib/esm/routing/index.d.ts +4 -0
- package/lib/esm/routing/index.d.ts.map +1 -1
- package/lib/esm/routing/index.js +5 -1
- package/lib/esm/routing/useNavigate.d.ts +6 -0
- package/lib/esm/routing/useNavigate.d.ts.map +1 -0
- package/lib/esm/routing/useNavigate.js +11 -0
- package/lib/esm/routing/useQuery.d.ts +2 -0
- package/lib/esm/routing/useQuery.d.ts.map +1 -0
- package/lib/esm/routing/useQuery.js +9 -0
- package/lib/esm/routing/useQueryState.d.ts +13 -0
- package/lib/esm/routing/useQueryState.d.ts.map +1 -0
- package/lib/esm/routing/useQueryState.js +80 -0
- package/lib/esm/routing/useTypedQuery.d.ts +2 -0
- package/lib/esm/routing/useTypedQuery.d.ts.map +1 -0
- package/lib/esm/routing/useTypedQuery.js +36 -0
- package/lib/esm/tools/buildSearch.d.ts +6 -0
- package/lib/esm/tools/buildSearch.d.ts.map +1 -0
- package/lib/esm/tools/buildSearch.js +60 -0
- package/lib/esm/tools/query-dsl.d.ts +28 -0
- package/lib/esm/tools/query-dsl.d.ts.map +1 -0
- package/lib/esm/tools/query-dsl.js +250 -0
- package/lib/esm/tools/query.d.ts +2 -0
- package/lib/esm/tools/query.d.ts.map +1 -0
- package/lib/esm/tools/query.js +43 -0
- package/lib/esm/tools.d.ts +2 -2
- package/lib/esm/tools.d.ts.map +1 -1
- package/lib/esm/tools.js +3 -2
- package/lib/esm/type-tests/query-infer.test-d.d.ts +2 -0
- package/lib/esm/type-tests/query-infer.test-d.d.ts.map +1 -0
- package/lib/esm/type-tests/query-infer.test-d.js +49 -0
- package/lib/esm/types.d.ts +28 -4
- package/lib/esm/types.d.ts.map +1 -1
- package/lib/esm/types.js +1 -1
- package/lib/tsconfig.esm.tsbuildinfo +1 -1
- package/lib/types/builder.d.ts.map +1 -1
- package/lib/types/eslint-rules/index.d.ts +2 -0
- package/lib/types/eslint-rules/index.d.ts.map +1 -0
- package/lib/types/eslint-rules/no-direct-window-location-search.d.ts +4 -0
- package/lib/types/eslint-rules/no-direct-window-location-search.d.ts.map +1 -0
- package/lib/types/history/BrowserHistory.d.ts.map +1 -1
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/lib/types/routing/Link.d.ts +1 -0
- package/lib/types/routing/Link.d.ts.map +1 -1
- package/lib/types/routing/RouteComponentWrapper.d.ts.map +1 -1
- package/lib/types/routing/createRouter.d.ts +7 -1
- package/lib/types/routing/createRouter.d.ts.map +1 -1
- package/lib/types/routing/index.d.ts +4 -0
- package/lib/types/routing/index.d.ts.map +1 -1
- package/lib/types/routing/useNavigate.d.ts +6 -0
- package/lib/types/routing/useNavigate.d.ts.map +1 -0
- package/lib/types/routing/useQuery.d.ts +2 -0
- package/lib/types/routing/useQuery.d.ts.map +1 -0
- package/lib/types/routing/useQueryState.d.ts +13 -0
- package/lib/types/routing/useQueryState.d.ts.map +1 -0
- package/lib/types/routing/useTypedQuery.d.ts +2 -0
- package/lib/types/routing/useTypedQuery.d.ts.map +1 -0
- package/lib/types/tools/buildSearch.d.ts +6 -0
- package/lib/types/tools/buildSearch.d.ts.map +1 -0
- package/lib/types/tools/query-dsl.d.ts +28 -0
- package/lib/types/tools/query-dsl.d.ts.map +1 -0
- package/lib/types/tools/query.d.ts +2 -0
- package/lib/types/tools/query.d.ts.map +1 -0
- package/lib/types/tools.d.ts +2 -2
- package/lib/types/tools.d.ts.map +1 -1
- package/lib/types/type-tests/query-infer.test-d.d.ts +2 -0
- package/lib/types/type-tests/query-infer.test-d.d.ts.map +1 -0
- package/lib/types/types.d.ts +28 -4
- package/lib/types/types.d.ts.map +1 -1
- package/package.json +7 -7
package/README.md
CHANGED
|
@@ -111,13 +111,15 @@ function Navigation() {
|
|
|
111
111
|
|
|
112
112
|
### Core Components
|
|
113
113
|
|
|
114
|
-
#### `createRouter(routes: Route[])`
|
|
114
|
+
#### `createRouter(routes: Route[], options?)`
|
|
115
115
|
|
|
116
116
|
Creates a router instance with the given route configuration.
|
|
117
117
|
|
|
118
118
|
**Parameters:**
|
|
119
119
|
|
|
120
120
|
- `routes`: Array of route definitions
|
|
121
|
+
- `options?`: Optional object
|
|
122
|
+
- `devtools?: boolean` Force enable/disable the global inspector. Defaults to enabled when `NODE_ENV !== 'production'`, disabled otherwise.
|
|
121
123
|
|
|
122
124
|
**Returns:**
|
|
123
125
|
|
|
@@ -228,6 +230,345 @@ Type helper for strongly-typed route definitions.
|
|
|
228
230
|
|
|
229
231
|
## Advanced Usage
|
|
230
232
|
|
|
233
|
+
### Typed Query Parameters (DSL)
|
|
234
|
+
|
|
235
|
+
The router provides a lightweight schema DSL for parsing, typing, normalizing and serializing query strings.
|
|
236
|
+
|
|
237
|
+
#### 1. Define a schema on the deepest route
|
|
238
|
+
|
|
239
|
+
```ts
|
|
240
|
+
import { q, r } from '@plumile/router';
|
|
241
|
+
|
|
242
|
+
const routes = [
|
|
243
|
+
r({
|
|
244
|
+
path: '/items',
|
|
245
|
+
// Schema: page = number (default 1), tag(s) = array of strings, flag = optional boolean
|
|
246
|
+
query: {
|
|
247
|
+
page: q.default(q.number(), 1),
|
|
248
|
+
tags: q.array(q.string()),
|
|
249
|
+
flag: q.optional(q.boolean()),
|
|
250
|
+
},
|
|
251
|
+
prepare: ({ query }) => {
|
|
252
|
+
// query is typed: { page: number; tags: string[]; flag?: boolean }
|
|
253
|
+
return { page: query.page };
|
|
254
|
+
},
|
|
255
|
+
render: () => null,
|
|
256
|
+
}),
|
|
257
|
+
];
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
#### 2. Access parsed & typed queries
|
|
261
|
+
|
|
262
|
+
```tsx
|
|
263
|
+
import { useQuery, useTypedQuery } from '@plumile/router';
|
|
264
|
+
|
|
265
|
+
function List() {
|
|
266
|
+
const raw = useQuery(); // Record<string, string | string[]>
|
|
267
|
+
const typed = useTypedQuery(); // Auto‑inferred from deepest route schema (no generic needed)
|
|
268
|
+
const [page, setPage] = useQueryState<number>('page'); // Bidirectional state ↔ URL for one param
|
|
269
|
+
return <pre>{JSON.stringify({ raw, typed }, null, 2)}</pre>;
|
|
270
|
+
}
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
Referential stability: both `raw` (from `useQuery()`) and `typed` (from `useTypedQuery()`) are memoized per canonical search string. If the URL search part doesn't change semantically (including key order canonicalization), the hook returns the exact same object reference. You can safely list either in React dependency arrays without extra `useMemo` or a hypothetical `useStableQuery` helper (not needed).
|
|
274
|
+
|
|
275
|
+
Type inference:
|
|
276
|
+
|
|
277
|
+
- If the matched deepest route has a `query` schema, `useTypedQuery()` returns the inferred `InferQuery<typeof schema>` shape automatically.
|
|
278
|
+
- If no schema exists, it returns the raw parsed object (record of string | string[]) so you can still read values safely.
|
|
279
|
+
- You can still supply a generic manually (`useTypedQuery<MyShape>()`) in edge cases (e.g. incremental migration) but it is usually unnecessary now.
|
|
280
|
+
|
|
281
|
+
#### 3. Programmatic navigation with typed query
|
|
282
|
+
|
|
283
|
+
```tsx
|
|
284
|
+
import { useNavigate } from '@plumile/router';
|
|
285
|
+
|
|
286
|
+
function Pager({ page }: { page: number }) {
|
|
287
|
+
const navigate = useNavigate();
|
|
288
|
+
return (
|
|
289
|
+
<button
|
|
290
|
+
onClick={() => {
|
|
291
|
+
navigate({ query: { page: page + 1 } });
|
|
292
|
+
}}
|
|
293
|
+
>
|
|
294
|
+
Next page
|
|
295
|
+
</button>
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
#### 4. Link component with query
|
|
301
|
+
|
|
302
|
+
```tsx
|
|
303
|
+
import { Link } from '@plumile/router';
|
|
304
|
+
|
|
305
|
+
<Link to="/items" query={{ page: 2, tags: ['a', 'b'], flag: true }}>
|
|
306
|
+
Filter
|
|
307
|
+
</Link>;
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
`Link` & `navigate` automatically serialize using the route schema, applying:
|
|
311
|
+
|
|
312
|
+
- Schema key order
|
|
313
|
+
- Array repetition (`?tags=a&tags=b`)
|
|
314
|
+
- Omission of default values when `omitDefaults` optimization applies internally
|
|
315
|
+
|
|
316
|
+
#### 5. Normalization
|
|
317
|
+
|
|
318
|
+
Built‑in simple normalization currently clamps `page < 1` to `1` and issues a `replaceState` to avoid polluting history.
|
|
319
|
+
|
|
320
|
+
#### 6. Serialization utility
|
|
321
|
+
|
|
322
|
+
```ts
|
|
323
|
+
import { buildSearch, q } from '@plumile/router';
|
|
324
|
+
|
|
325
|
+
const schema = {
|
|
326
|
+
page: q.default(q.number(), 1),
|
|
327
|
+
tag: q.array(q.string()),
|
|
328
|
+
} as const;
|
|
329
|
+
const search = buildSearch({ page: 1, tag: ['x', 'y'] }, schema, {
|
|
330
|
+
omitDefaults: true,
|
|
331
|
+
});
|
|
332
|
+
// => '?tag=x&tag=y'
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
#### 7. Parsing utility / alias
|
|
336
|
+
|
|
337
|
+
```ts
|
|
338
|
+
import { parseSearch, q } from '@plumile/router';
|
|
339
|
+
|
|
340
|
+
const schema = { flag: q.boolean() } as const;
|
|
341
|
+
const typed = parseSearch(schema, '?flag=1'); // { flag: true }
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
#### 8. Performance and stability
|
|
345
|
+
|
|
346
|
+
There are two coordinated caching layers:
|
|
347
|
+
|
|
348
|
+
1. Raw query cache: A process-wide Map keyed by a canonicalized search string (sorted keys, ordered value emission). Produces a frozen empty object for the empty search and reuses prior parsed objects, yielding stable references for unchanged search state.
|
|
349
|
+
2. Typed query cache: A WeakMap keyed by (schema reference → canonical search signature) that parses once and reuses the typed value. Structural deep-equality canonicalization means semantically equivalent searches (e.g. reordered keys) reuse object identity.
|
|
350
|
+
|
|
351
|
+
Effects:
|
|
352
|
+
|
|
353
|
+
- Stable object identity for both raw and typed queries eliminates needless renders and removes the need for an extra `useStableQuery` hook.
|
|
354
|
+
- Safe to put `useQuery()` / `useTypedQuery()` results directly in dependency arrays (`useEffect`, `useMemo`, selectors, etc.).
|
|
355
|
+
- Empty query allocations are avoided (shared frozen object).
|
|
356
|
+
|
|
357
|
+
Guideline: If you need to derive lightweight projections (e.g. `const { page } = typed`), you can still destructure; but avoid spreading into a new object if you rely on reference equality downstream.
|
|
358
|
+
|
|
359
|
+
#### Devtools / Inspection
|
|
360
|
+
|
|
361
|
+
In development (`NODE_ENV !== 'production'` by default, or when `createRouter(..., { devtools: true })` is passed), the router exposes a lightweight global inspector.
|
|
362
|
+
|
|
363
|
+
Optionally you can enable an in‑page overlay panel for quick visual inspection:
|
|
364
|
+
|
|
365
|
+
```ts
|
|
366
|
+
createRouter(routes, {
|
|
367
|
+
devtools: { panel: true, global: true, shortcut: 'Alt+Shift+R' },
|
|
368
|
+
});
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
Devtools option forms:
|
|
372
|
+
|
|
373
|
+
- `devtools: true | false` (boolean) – legacy form, controls global only.
|
|
374
|
+
- `devtools: { global?: boolean; panel?: boolean; shortcut?: string }` – granular.
|
|
375
|
+
- `global` (default: NODE_ENV !== 'production') exposes `window.__PLUMILE_ROUTER__`.
|
|
376
|
+
- `panel` (default: false) mounts an overlay; closed with the close button or page reload.
|
|
377
|
+
- `shortcut` (default: `Alt+Shift+R`) toggles panel visibility.
|
|
378
|
+
|
|
379
|
+
The panel displays current path+search, variables, raw query and typed query. It is intentionally framework‑agnostic (no React runtime cost) and uses a shadow root to minimize style collisions.
|
|
380
|
+
|
|
381
|
+
```js
|
|
382
|
+
window.__PLUMILE_ROUTER__.get(); // current RouteEntry
|
|
383
|
+
const unsub = window.__PLUMILE_ROUTER__.subscribe((entry) =>
|
|
384
|
+
console.log(entry.typedQuery),
|
|
385
|
+
);
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
This lets you introspect parsed queries & variables without adding debug code. Neither global nor panel is present in production unless explicitly forced with `devtools: { global: true, panel: true }` (discouraged).
|
|
389
|
+
|
|
390
|
+
##### Detailed Usage
|
|
391
|
+
|
|
392
|
+
The global is intentionally tiny to avoid coupling and bundle weight. It only appears when the devtools flag resolves truthy:
|
|
393
|
+
|
|
394
|
+
1. Explicit: `createRouter(routes, { devtools: true })`
|
|
395
|
+
2. Implicit heuristic: `NODE_ENV !== 'production'`
|
|
396
|
+
3. Disabled explicitly: `createRouter(routes, { devtools: false })`
|
|
397
|
+
|
|
398
|
+
Always guard in snippets that might be copied to production code:
|
|
399
|
+
|
|
400
|
+
```js
|
|
401
|
+
if (window.__PLUMILE_ROUTER__) {
|
|
402
|
+
console.log(window.__PLUMILE_ROUTER__.get());
|
|
403
|
+
}
|
|
404
|
+
```
|
|
405
|
+
|
|
406
|
+
`get()` returns the current `RouteEntry` (simplified shape):
|
|
407
|
+
|
|
408
|
+
```ts
|
|
409
|
+
type RouteEntry = {
|
|
410
|
+
location: Location; // window.location snapshot
|
|
411
|
+
route: { match; params; path } | null; // current matched route (or null)
|
|
412
|
+
preparedMatch: { routes: { prepared; render?; resourcePage? }[]; match }; // internal prepared tree
|
|
413
|
+
forceRerender: boolean; // indicates forced re-render situations
|
|
414
|
+
rawSearch: string; // '?page=2&tag=a'
|
|
415
|
+
query: Record<string, string | string[]>; // raw aggregated query params
|
|
416
|
+
typedQuery: any; // typed query if schema present
|
|
417
|
+
};
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Common console patterns:
|
|
421
|
+
|
|
422
|
+
1. Log every navigation with typed query & params:
|
|
423
|
+
|
|
424
|
+
```js
|
|
425
|
+
const dev = window.__PLUMILE_ROUTER__;
|
|
426
|
+
if (dev) {
|
|
427
|
+
const off = dev.subscribe((e) => {
|
|
428
|
+
console.log('[router]', e.location.pathname + e.location.search, {
|
|
429
|
+
vars: e.route?.params,
|
|
430
|
+
typed: e.typedQuery,
|
|
431
|
+
});
|
|
432
|
+
});
|
|
433
|
+
// later: off();
|
|
434
|
+
}
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
2. Inspect prepared data for the deepest route (last element):
|
|
438
|
+
|
|
439
|
+
```js
|
|
440
|
+
const entry = window.__PLUMILE_ROUTER__?.get();
|
|
441
|
+
const deepest = entry?.preparedMatch.routes.at(-1);
|
|
442
|
+
deepest?.prepared; // Prepared data returned by deepest prepare()
|
|
443
|
+
```
|
|
444
|
+
|
|
445
|
+
3. Quick diff watcher for query changes only:
|
|
446
|
+
|
|
447
|
+
```js
|
|
448
|
+
let last = window.__PLUMILE_ROUTER__?.get().rawSearch;
|
|
449
|
+
const off = window.__PLUMILE_ROUTER__?.subscribe((e) => {
|
|
450
|
+
if (e.rawSearch !== last) {
|
|
451
|
+
console.log('query changed', last, '=>', e.rawSearch, e.typedQuery);
|
|
452
|
+
last = e.rawSearch;
|
|
453
|
+
}
|
|
454
|
+
});
|
|
455
|
+
```
|
|
456
|
+
|
|
457
|
+
4. Measuring parse performance (rough dev-only micro‑benchmark):
|
|
458
|
+
|
|
459
|
+
```js
|
|
460
|
+
const { get } = window.__PLUMILE_ROUTER__;
|
|
461
|
+
const before = performance.now();
|
|
462
|
+
for (let i = 0; i < 200; i++) get().typedQuery; // use cache; ensures no GC
|
|
463
|
+
console.log('elapsed ms', performance.now() - before);
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
5. Safe optional chaining helper (copy/paste):
|
|
467
|
+
|
|
468
|
+
```js
|
|
469
|
+
const R = window.__PLUMILE_ROUTER__;
|
|
470
|
+
R && R.subscribe((e) => console.debug('[typedQuery]', e.typedQuery));
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
Unsubscribing: every `subscribe` returns a disposer function. Always call it if you set up long‑lived listeners in a debugging session to avoid memory leaks during hot reloads.
|
|
474
|
+
|
|
475
|
+
Extending: if you need more (e.g. trigger navigations) you can wrap `createRouter` in your app and attach additional methods to `window.__PLUMILE_ROUTER__` (e.g. `navigate: context.navigate`) — omitted by default to avoid accidental production reliance.
|
|
476
|
+
|
|
477
|
+
Production: the symbol is not defined; accessing it will yield `undefined`. Never ship logic depending on it; keep usage inside `if (process.env.NODE_ENV !== 'production')` blocks or guarded optional checks.
|
|
478
|
+
|
|
479
|
+
### ESLint Rule: no-direct-window-location-search
|
|
480
|
+
|
|
481
|
+
To encourage consistent usage of the query hooks, a custom rule is provided inside the router package to flag raw `window.location.search` access.
|
|
482
|
+
|
|
483
|
+
Add to your flat ESLint config:
|
|
484
|
+
|
|
485
|
+
```js
|
|
486
|
+
import noDirectWindowLocationSearch from '@plumile/router/lib/eslint-rules/no-direct-window-location-search.js';
|
|
487
|
+
|
|
488
|
+
export default [
|
|
489
|
+
{
|
|
490
|
+
plugins: {
|
|
491
|
+
'@plumile-router/dx': {
|
|
492
|
+
rules: {
|
|
493
|
+
'no-direct-window-location-search': noDirectWindowLocationSearch,
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
},
|
|
497
|
+
rules: {
|
|
498
|
+
'@plumile-router/dx/no-direct-window-location-search': 'warn',
|
|
499
|
+
},
|
|
500
|
+
},
|
|
501
|
+
];
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
Optional configuration:
|
|
505
|
+
|
|
506
|
+
```js
|
|
507
|
+
// allow some files (e.g. legacy bootstrap) to keep direct access
|
|
508
|
+
rules: {
|
|
509
|
+
'@plumile-router/dx/no-direct-window-location-search': [
|
|
510
|
+
'warn',
|
|
511
|
+
{ allowInFiles: ['legacy-entry.ts'] },
|
|
512
|
+
],
|
|
513
|
+
},
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
When triggered, replace patterns like:
|
|
517
|
+
|
|
518
|
+
```ts
|
|
519
|
+
const qs = window.location.search;
|
|
520
|
+
```
|
|
521
|
+
|
|
522
|
+
with:
|
|
523
|
+
|
|
524
|
+
```ts
|
|
525
|
+
const query = useQuery(); // or useTypedQuery()
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
### Migration Guide (Phases 1 → 5)
|
|
529
|
+
|
|
530
|
+
1. Phase 1/2: Upgrade — no schema needed. Use `useQuery()` for raw params.
|
|
531
|
+
2. Phase 3: Add `query` schema to your deepest route; adopt `useTypedQuery()` where type safety is desirable.
|
|
532
|
+
3. Phase 4: Replace manual URL building with `navigate({ query })` or `<Link query={...} />`. Remove ad‑hoc serialization logic.
|
|
533
|
+
4. Phase 5: Move lightweight data loading logic that depends on query into `prepare({ query })` (now typed). Rely on built‑in normalization (e.g. page clamp) or add custom normalization inside `prepare` followed by a `navigate({ replace: true, query: normalized })` if needed.
|
|
534
|
+
5. Optional: Use `buildSearch` / `parseSearch` for unit tests & utilities.
|
|
535
|
+
|
|
536
|
+
### Query Descriptor Reference
|
|
537
|
+
|
|
538
|
+
| Descriptor | Description | Serialize Example |
|
|
539
|
+
| -------------------------------- | --------------------------------------------------- | ------------------------------------ |
|
|
540
|
+
| `q.string()` | Last occurrence string | `{ q: 'x' } -> ?q=x` |
|
|
541
|
+
| `q.number()` | Number (invalid => undefined) | `{ n: 2 } -> ?n=2` |
|
|
542
|
+
| `q.boolean()` | Presence / true/false/1/0 | `{ f: true } -> ?f=1` |
|
|
543
|
+
| `q.enum('a','b')` | Restricted string | `{ e: 'a' } -> ?e=a` |
|
|
544
|
+
| `q.array(inner)` | Repeated key multi-values | `{ tag: ['x','y'] } -> ?tag=x&tag=y` |
|
|
545
|
+
| `q.optional(d)` | Marks descriptor optional | omitted if undefined |
|
|
546
|
+
| `q.default(d, v)` | Supplies default + omit on serialize (omitDefaults) | default skipped |
|
|
547
|
+
| `q.emptyAsUndefined(q.string())` | Maps empty string '' to undefined | omitted |
|
|
548
|
+
| `q.custom({ parse, serialize })` | Custom parse/serialize logic | depends |
|
|
549
|
+
|
|
550
|
+
Custom: `q.custom({ parse(values), serialize(value) })` lets you wire bespoke formats. Ensure `serialize` outputs an array of raw string values. Use sparingly to keep schemas readable.
|
|
551
|
+
|
|
552
|
+
### useQueryState Hook
|
|
553
|
+
|
|
554
|
+
`useQueryState(key, opts?)` creates a controlled binding between a single query parameter and component state.
|
|
555
|
+
|
|
556
|
+
```tsx
|
|
557
|
+
const [page, setPage] = useQueryState<number>('page');
|
|
558
|
+
// Increment page without pushing a new history entry
|
|
559
|
+
setPage(page! + 1, { replace: true });
|
|
560
|
+
```
|
|
561
|
+
|
|
562
|
+
Behavior:
|
|
563
|
+
|
|
564
|
+
- Reads from typedQuery if schema present, else raw query.
|
|
565
|
+
- Respects schema defaults (and `defaultValue` override in options) and omits key when value equals default (with `omitIfDefault: true`).
|
|
566
|
+
- Pass `{ raw: true }` to force raw (string) source for incremental migrations.
|
|
567
|
+
- Uses existing navigation serialization (ordering, omit defaults, arrays).
|
|
568
|
+
|
|
569
|
+
Options:
|
|
570
|
+
`{ defaultValue?, omitIfDefault?: boolean = true, replace?: boolean, raw?: boolean }`
|
|
571
|
+
|
|
231
572
|
### Data Preloading
|
|
232
573
|
|
|
233
574
|
```typescript
|
package/lib/esm/builder.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQlE,qBAAa,SAAS,CAAC,OAAO,SAAS,SAAS;IAEvC,IAAI,EAAE,MAAM,CAAC;IAGb,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;IAG1B,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAGtC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAOR,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC;CAOlD;AAQD,wBAAgB,UAAU,CACxB,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,GAChC,KAAK,IAAI,QAAQ,CAGnB;AAYD,wBAAgB,UAAU,CACxB,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,EAAE,EAC3C,YAAY,GAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAO,EACpC,MAAM,SAAK,GACV,SAAS,CAAC,GAAG,CAAC,EAAE,
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAQlE,qBAAa,SAAS,CAAC,OAAO,SAAS,SAAS;IAEvC,IAAI,EAAE,MAAM,CAAC;IAGb,MAAM,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;IAG1B,aAAa,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IAGtC,UAAU,CAAC,EAAE,MAAM,CAAC;gBAOR,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC;CAOlD;AAQD,wBAAgB,UAAU,CACxB,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,GAChC,KAAK,IAAI,QAAQ,CAGnB;AAYD,wBAAgB,UAAU,CACxB,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,EAAE,EAC3C,YAAY,GAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAO,EACpC,MAAM,SAAK,GACV,SAAS,CAAC,GAAG,CAAC,EAAE,CA8DlB;AASD,wBAAgB,WAAW,CAAC,WAAW,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,EAAE,CAE5E"}
|
package/lib/esm/builder.js
CHANGED
|
@@ -23,7 +23,11 @@ export function buildRoute(routeConfig, parentRoutes = [], prefix = '') {
|
|
|
23
23
|
parts.push(prefix);
|
|
24
24
|
}
|
|
25
25
|
if (route.path != null && route.path !== '' && route.path !== '/') {
|
|
26
|
-
|
|
26
|
+
let normalized = route.path;
|
|
27
|
+
if (normalized.startsWith('/')) {
|
|
28
|
+
normalized = normalized.slice(1);
|
|
29
|
+
}
|
|
30
|
+
parts.push(normalized);
|
|
27
31
|
}
|
|
28
32
|
const newPath = parts.join('/');
|
|
29
33
|
const { children } = route;
|
|
@@ -35,7 +39,10 @@ export function buildRoute(routeConfig, parentRoutes = [], prefix = '') {
|
|
|
35
39
|
const matchFunction = match(`/${newPath}`, {
|
|
36
40
|
trailing: false,
|
|
37
41
|
});
|
|
38
|
-
|
|
42
|
+
let path = newPath;
|
|
43
|
+
if (!newPath.startsWith('/')) {
|
|
44
|
+
path = `/${newPath}`;
|
|
45
|
+
}
|
|
39
46
|
if (isRedirect(route)) {
|
|
40
47
|
let redirectTo = route.to;
|
|
41
48
|
if (!redirectTo.startsWith('/')) {
|
|
@@ -61,4 +68,4 @@ export function buildRoute(routeConfig, parentRoutes = [], prefix = '') {
|
|
|
61
68
|
export function buildRoutes(routeConfig) {
|
|
62
69
|
return buildRoute(routeConfig);
|
|
63
70
|
}
|
|
64
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
71
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9idWlsZGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxLQUFLLEVBQXNDLE1BQU0sZ0JBQWdCLENBQUM7QUFVM0UsTUFBTSxPQUFPLFNBQVM7SUFFYixJQUFJLENBQVM7SUFHYixNQUFNLENBQW9CO0lBRzFCLGFBQWEsQ0FBeUI7SUFHdEMsVUFBVSxDQUFVO0lBTzNCLFlBQW1CLEtBQThCO1FBQy9DLE1BQU0sRUFBRSxhQUFhLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxNQUFNLEVBQUUsR0FBRyxLQUFLLENBQUM7UUFDMUQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsSUFBSSxDQUFDLFVBQVUsR0FBRyxVQUFVLENBQUM7UUFDN0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsR0FBRyxhQUFhLENBQUM7SUFDckMsQ0FBQztDQUNGO0FBUUQsTUFBTSxVQUFVLFVBQVUsQ0FDeEIsS0FBaUM7SUFHakMsT0FBUSxLQUFrQixDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUM7QUFDeEMsQ0FBQztBQVlELE1BQU0sVUFBVSxVQUFVLENBQ3hCLFdBQTJDLEVBQzNDLGVBQWtDLEVBQUUsRUFDcEMsTUFBTSxHQUFHLEVBQUU7SUFFWCxNQUFNLFVBQVUsR0FBcUIsRUFBRSxDQUFDO0lBRXhDLEtBQUssTUFBTSxLQUFLLElBQUksV0FBVyxFQUFFLENBQUM7UUFDaEMsTUFBTSxLQUFLLEdBQUcsRUFBRSxDQUFDO1FBQ2pCLElBQUksTUFBTSxLQUFLLEVBQUUsRUFBRSxDQUFDO1lBQ2xCLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckIsQ0FBQztRQUNELElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxJQUFJLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxFQUFFLElBQUksS0FBSyxDQUFDLElBQUksS0FBSyxHQUFHLEVBQUUsQ0FBQztZQUNsRSxJQUFJLFVBQVUsR0FBRyxLQUFLLENBQUMsSUFBSSxDQUFDO1lBQzVCLElBQUksVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUMvQixVQUFVLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNuQyxDQUFDO1lBQ0QsS0FBSyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUN6QixDQUFDO1FBRUQsTUFBTSxPQUFPLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUVoQyxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsS0FBd0IsQ0FBQztRQUU5QyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxJQUFJLFFBQVEsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUMzQyxNQUFNLE1BQU0sR0FBRyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUMsR0FBRyxZQUFZLEVBQUUsS0FBSyxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7WUFDdkUsVUFBVSxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sQ0FBQyxDQUFDO1lBRTNCLFNBQVM7UUFDWCxDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsS0FBSyxDQUFDLElBQUksT0FBTyxFQUFFLEVBQUU7WUFDekMsUUFBUSxFQUFFLEtBQUs7U0FDaEIsQ0FBQyxDQUFDO1FBRUgsSUFBSSxJQUFJLEdBQUcsT0FBTyxDQUFDO1FBQ25CLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDN0IsSUFBSSxHQUFHLElBQUksT0FBTyxFQUFFLENBQUM7UUFDdkIsQ0FBQztRQUVELElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEIsSUFBSSxVQUFVLEdBQUcsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUUxQixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNoQyxVQUFVLEdBQUcsR0FBRyxJQUFJLElBQUksVUFBVSxFQUFFLENBQUM7WUFDdkMsQ0FBQztZQUNELFVBQVUsQ0FBQyxJQUFJLENBQ2IsSUFBSSxTQUFTLENBQUM7Z0JBQ1osSUFBSTtnQkFDSixVQUFVO2dCQUNWLGFBQWE7Z0JBQ2IsTUFBTSxFQUFFLENBQUMsR0FBRyxZQUFZLENBQUM7YUFDMUIsQ0FBQyxDQUNILENBQUM7UUFDSixDQUFDO2FBQU0sQ0FBQztZQUNOLFVBQVUsQ0FBQyxJQUFJLENBQ2IsSUFBSSxTQUFTLENBQUM7Z0JBQ1osSUFBSTtnQkFDSixhQUFhO2dCQUNiLE1BQU0sRUFBRSxDQUFDLEdBQUcsWUFBWSxFQUFFLEtBQUssQ0FBQzthQUNqQyxDQUFDLENBQ0gsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxVQUFVLENBQUM7QUFDcEIsQ0FBQztBQVNELE1BQU0sVUFBVSxXQUFXLENBQUMsV0FBOEI7SUFDeEQsT0FBTyxVQUFVLENBQUMsV0FBVyxDQUFDLENBQUM7QUFDakMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IG1hdGNoLCB0eXBlIE1hdGNoRnVuY3Rpb24sIHR5cGUgUGFyYW1EYXRhIH0gZnJvbSAncGF0aC10by1yZWdleHAnO1xuXG5pbXBvcnQgdHlwZSB7IEZsYXRSb3V0ZUlucHV0LCBSZWRpcmVjdCwgUm91dGUgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBSZXByZXNlbnRzIGEgZmxhdHRlbmVkIHJvdXRlIHdpdGggYSBjb21waWxlZCBtYXRjaCBmdW5jdGlvbi5cbiAqIFRoaXMgaXMgYW4gaW50ZXJuYWwgcmVwcmVzZW50YXRpb24gdXNlZCBieSB0aGUgcm91dGVyIHRvIGVmZmljaWVudGx5IG1hdGNoIFVSTHMuXG4gKlxuICogQHRlbXBsYXRlIFRQYXJhbXMgLSBSb3V0ZSBwYXJhbWV0ZXIgdHlwZXMgZXh0cmFjdGVkIGZyb20gdGhlIFVSTCBwYXRoXG4gKi9cbmV4cG9ydCBjbGFzcyBGbGF0Um91dGU8VFBhcmFtcyBleHRlbmRzIFBhcmFtRGF0YT4ge1xuICAvKiogVGhlIFVSTCBwYXRoIHBhdHRlcm4gZm9yIHRoaXMgcm91dGUgKi9cbiAgcHVibGljIHBhdGg6IHN0cmluZztcblxuICAvKiogTmVzdGVkIHJvdXRlcyB0aGF0IHNob3VsZCBiZSByZW5kZXJlZCB3aXRoaW4gdGhpcyByb3V0ZSAqL1xuICBwdWJsaWMgcm91dGVzOiBSb3V0ZTxhbnksIGFueT5bXTtcblxuICAvKiogQ29tcGlsZWQgZnVuY3Rpb24gdG8gbWF0Y2ggVVJMIHBhdGhzIGFnYWluc3QgdGhpcyByb3V0ZSBwYXR0ZXJuICovXG4gIHB1YmxpYyBtYXRjaEZ1bmN0aW9uOiBNYXRjaEZ1bmN0aW9uPFRQYXJhbXM+O1xuXG4gIC8qKiBPcHRpb25hbCByZWRpcmVjdCBkZXN0aW5hdGlvbiBpZiB0aGlzIHJvdXRlIHNob3VsZCByZWRpcmVjdCAqL1xuICBwdWJsaWMgcmVkaXJlY3RUbz86IHN0cmluZztcblxuICAvKipcbiAgICogQ3JlYXRlcyBhIG5ldyBGbGF0Um91dGUgaW5zdGFuY2UuXG4gICAqXG4gICAqIEBwYXJhbSBpbnB1dCAtIENvbmZpZ3VyYXRpb24gZm9yIHRoZSBmbGF0IHJvdXRlXG4gICAqL1xuICBwdWJsaWMgY29uc3RydWN0b3IoaW5wdXQ6IEZsYXRSb3V0ZUlucHV0PFRQYXJhbXM+KSB7XG4gICAgY29uc3QgeyBtYXRjaEZ1bmN0aW9uLCBwYXRoLCByZWRpcmVjdFRvLCByb3V0ZXMgfSA9IGlucHV0O1xuICAgIHRoaXMucGF0aCA9IHBhdGg7XG4gICAgdGhpcy5yZWRpcmVjdFRvID0gcmVkaXJlY3RUbztcbiAgICB0aGlzLnJvdXRlcyA9IHJvdXRlcztcbiAgICB0aGlzLm1hdGNoRnVuY3Rpb24gPSBtYXRjaEZ1bmN0aW9uO1xuICB9XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCB0byBjaGVjayBpZiBhIHJvdXRlIGNvbmZpZ3VyYXRpb24gaXMgYSByZWRpcmVjdC5cbiAqXG4gKiBAcGFyYW0gcm91dGUgLSBSb3V0ZSBvciByZWRpcmVjdCBjb25maWd1cmF0aW9uIHRvIGNoZWNrXG4gKiBAcmV0dXJucyBUcnVlIGlmIHRoZSByb3V0ZSBpcyBhIHJlZGlyZWN0IGNvbmZpZ3VyYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmVkaXJlY3QoXG4gIHJvdXRlOiBSb3V0ZTxhbnksIGFueT4gfCBSZWRpcmVjdCxcbik6IHJvdXRlIGlzIFJlZGlyZWN0IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bm5lY2Vzc2FyeS1jb25kaXRpb25cbiAgcmV0dXJuIChyb3V0ZSBhcyBSZWRpcmVjdCkudG8gIT0gbnVsbDtcbn1cblxuLyoqXG4gKiBSZWN1cnNpdmVseSBidWlsZHMgYSBmbGF0IGxpc3Qgb2Ygcm91dGVzIGZyb20gYSBuZXN0ZWQgcm91dGUgY29uZmlndXJhdGlvbi5cbiAqIFRoaXMgZnVuY3Rpb24gcHJvY2Vzc2VzIHRoZSByb3V0ZSB0cmVlIGFuZCBjcmVhdGVzIEZsYXRSb3V0ZSBpbnN0YW5jZXMgd2l0aFxuICogY29tcGlsZWQgcGF0aCBtYXRjaGVycyBmb3IgZWZmaWNpZW50IFVSTCBtYXRjaGluZy5cbiAqXG4gKiBAcGFyYW0gcm91dGVDb25maWcgLSBBcnJheSBvZiByb3V0ZSBvciByZWRpcmVjdCBjb25maWd1cmF0aW9uc1xuICogQHBhcmFtIHBhcmVudFJvdXRlcyAtIFBhcmVudCByb3V0ZXMgaW4gdGhlIGN1cnJlbnQgcGF0aCAoZm9yIG5lc3RlZCByb3V0ZXMpXG4gKiBAcGFyYW0gcHJlZml4IC0gVVJMIHByZWZpeCBmcm9tIHBhcmVudCByb3V0ZXNcbiAqIEByZXR1cm5zIEFycmF5IG9mIGZsYXR0ZW5lZCByb3V0ZXMgcmVhZHkgZm9yIG1hdGNoaW5nXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFJvdXRlKFxuICByb3V0ZUNvbmZpZzogKFJvdXRlPGFueSwgYW55PiB8IFJlZGlyZWN0KVtdLFxuICBwYXJlbnRSb3V0ZXM6IFJvdXRlPGFueSwgYW55PltdID0gW10sXG4gIHByZWZpeCA9ICcnLFxuKTogRmxhdFJvdXRlPGFueT5bXSB7XG4gIGNvbnN0IGZsYXRSb3V0ZXM6IEZsYXRSb3V0ZTxhbnk+W10gPSBbXTtcblxuICBmb3IgKGNvbnN0IHJvdXRlIG9mIHJvdXRlQ29uZmlnKSB7XG4gICAgY29uc3QgcGFydHMgPSBbXTtcbiAgICBpZiAocHJlZml4ICE9PSAnJykge1xuICAgICAgcGFydHMucHVzaChwcmVmaXgpO1xuICAgIH1cbiAgICBpZiAocm91dGUucGF0aCAhPSBudWxsICYmIHJvdXRlLnBhdGggIT09ICcnICYmIHJvdXRlLnBhdGggIT09ICcvJykge1xuICAgICAgbGV0IG5vcm1hbGl6ZWQgPSByb3V0ZS5wYXRoO1xuICAgICAgaWYgKG5vcm1hbGl6ZWQuc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgIG5vcm1hbGl6ZWQgPSBub3JtYWxpemVkLnNsaWNlKDEpO1xuICAgICAgfVxuICAgICAgcGFydHMucHVzaChub3JtYWxpemVkKTtcbiAgICB9XG5cbiAgICBjb25zdCBuZXdQYXRoID0gcGFydHMuam9pbignLycpO1xuXG4gICAgY29uc3QgeyBjaGlsZHJlbiB9ID0gcm91dGUgYXMgUm91dGU8YW55LCBhbnk+O1xuXG4gICAgaWYgKCFpc1JlZGlyZWN0KHJvdXRlKSAmJiBjaGlsZHJlbiAhPSBudWxsKSB7XG4gICAgICBjb25zdCByb3V0ZXMgPSBidWlsZFJvdXRlKGNoaWxkcmVuLCBbLi4ucGFyZW50Um91dGVzLCByb3V0ZV0sIG5ld1BhdGgpO1xuICAgICAgZmxhdFJvdXRlcy5wdXNoKC4uLnJvdXRlcyk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY29udGludWVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIGNvbnN0IG1hdGNoRnVuY3Rpb24gPSBtYXRjaChgLyR7bmV3UGF0aH1gLCB7XG4gICAgICB0cmFpbGluZzogZmFsc2UsXG4gICAgfSk7XG5cbiAgICBsZXQgcGF0aCA9IG5ld1BhdGg7XG4gICAgaWYgKCFuZXdQYXRoLnN0YXJ0c1dpdGgoJy8nKSkge1xuICAgICAgcGF0aCA9IGAvJHtuZXdQYXRofWA7XG4gICAgfVxuXG4gICAgaWYgKGlzUmVkaXJlY3Qocm91dGUpKSB7XG4gICAgICBsZXQgcmVkaXJlY3RUbyA9IHJvdXRlLnRvO1xuXG4gICAgICBpZiAoIXJlZGlyZWN0VG8uc3RhcnRzV2l0aCgnLycpKSB7XG4gICAgICAgIHJlZGlyZWN0VG8gPSBgJHtwYXRofS8ke3JlZGlyZWN0VG99YDtcbiAgICAgIH1cbiAgICAgIGZsYXRSb3V0ZXMucHVzaChcbiAgICAgICAgbmV3IEZsYXRSb3V0ZSh7XG4gICAgICAgICAgcGF0aCxcbiAgICAgICAgICByZWRpcmVjdFRvLFxuICAgICAgICAgIG1hdGNoRnVuY3Rpb24sXG4gICAgICAgICAgcm91dGVzOiBbLi4ucGFyZW50Um91dGVzXSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICBmbGF0Um91dGVzLnB1c2goXG4gICAgICAgIG5ldyBGbGF0Um91dGUoe1xuICAgICAgICAgIHBhdGgsXG4gICAgICAgICAgbWF0Y2hGdW5jdGlvbixcbiAgICAgICAgICByb3V0ZXM6IFsuLi5wYXJlbnRSb3V0ZXMsIHJvdXRlXSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmbGF0Um91dGVzO1xufVxuXG4vKipcbiAqIEJ1aWxkcyBhIGZsYXQgcm91dGUgbGlzdCBmcm9tIHRoZSBnaXZlbiByb3V0ZSBjb25maWd1cmF0aW9uLlxuICogVGhpcyBpcyB0aGUgbWFpbiBlbnRyeSBwb2ludCBmb3Igcm91dGUgYnVpbGRpbmcuXG4gKlxuICogQHBhcmFtIHJvdXRlQ29uZmlnIC0gQXJyYXkgb2Ygcm91dGUgY29uZmlndXJhdGlvbnMgdG8gZmxhdHRlblxuICogQHJldHVybnMgQXJyYXkgb2YgZmxhdHRlbmVkIHJvdXRlcyByZWFkeSBmb3IgbWF0Y2hpbmdcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUm91dGVzKHJvdXRlQ29uZmlnOiBSb3V0ZTxhbnksIGFueT5bXSk6IEZsYXRSb3V0ZTxhbnk+W10ge1xuICByZXR1cm4gYnVpbGRSb3V0ZShyb3V0ZUNvbmZpZyk7XG59XG4iXX0=
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/eslint-rules/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,4BAA4B,EAAE,MAAM,uCAAuC,CAAC"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
export { default as noDirectWindowLocationSearch } from './no-direct-window-location-search.js';
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50LXJ1bGVzL2luZGV4LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxPQUFPLElBQUksNEJBQTRCLEVBQUUsTUFBTSx1Q0FBdUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCB7IGRlZmF1bHQgYXMgbm9EaXJlY3RXaW5kb3dMb2NhdGlvblNlYXJjaCB9IGZyb20gJy4vbm8tZGlyZWN0LXdpbmRvdy1sb2NhdGlvbi1zZWFyY2guanMnO1xuIl19
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-direct-window-location-search.d.ts","sourceRoot":"","sources":["../../../src/eslint-rules/no-direct-window-location-search.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAMnC,QAAA,MAAM,IAAI,EAAE,IAAI,CAAC,UAmDhB,CAAC;AAEF,eAAe,IAAI,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
const rule = {
|
|
2
|
+
meta: {
|
|
3
|
+
type: 'suggestion',
|
|
4
|
+
docs: {
|
|
5
|
+
description: 'Discourage direct window.location.search access; use useQuery()/useTypedQuery() instead',
|
|
6
|
+
recommended: false,
|
|
7
|
+
},
|
|
8
|
+
messages: {
|
|
9
|
+
avoid: 'Avoid direct access to window.location.search. Use useQuery() / useTypedQuery() from @plumile/router.',
|
|
10
|
+
},
|
|
11
|
+
schema: [
|
|
12
|
+
{
|
|
13
|
+
type: 'object',
|
|
14
|
+
properties: {
|
|
15
|
+
allowInFiles: { type: 'array', items: { type: 'string' } },
|
|
16
|
+
},
|
|
17
|
+
additionalProperties: false,
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
create(context) {
|
|
22
|
+
const rawOption = context.options[0];
|
|
23
|
+
const allowIn = new Set(rawOption?.allowInFiles ?? []);
|
|
24
|
+
const filename = context.getFilename();
|
|
25
|
+
const isAllowed = [...allowIn].some((pat) => {
|
|
26
|
+
return filename.includes(pat);
|
|
27
|
+
});
|
|
28
|
+
return {
|
|
29
|
+
MemberExpression(node) {
|
|
30
|
+
if (isAllowed)
|
|
31
|
+
return;
|
|
32
|
+
if (node.property.type === 'Identifier' &&
|
|
33
|
+
node.property.name === 'search' &&
|
|
34
|
+
node.object.type === 'MemberExpression') {
|
|
35
|
+
const obj = node.object;
|
|
36
|
+
if (obj.property.type === 'Identifier' &&
|
|
37
|
+
obj.property.name === 'location' &&
|
|
38
|
+
obj.object.type === 'Identifier' &&
|
|
39
|
+
obj.object.name === 'window') {
|
|
40
|
+
context.report({ node, messageId: 'avoid' });
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
},
|
|
46
|
+
};
|
|
47
|
+
export default rule;
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibm8tZGlyZWN0LXdpbmRvdy1sb2NhdGlvbi1zZWFyY2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZXNsaW50LXJ1bGVzL25vLWRpcmVjdC13aW5kb3ctbG9jYXRpb24tc2VhcmNoLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE1BQU0sSUFBSSxHQUFvQjtJQUM1QixJQUFJLEVBQUU7UUFDSixJQUFJLEVBQUUsWUFBWTtRQUNsQixJQUFJLEVBQUU7WUFDSixXQUFXLEVBQ1QseUZBQXlGO1lBQzNGLFdBQVcsRUFBRSxLQUFLO1NBQ25CO1FBQ0QsUUFBUSxFQUFFO1lBQ1IsS0FBSyxFQUNILHVHQUF1RztTQUMxRztRQUNELE1BQU0sRUFBRTtZQUNOO2dCQUNFLElBQUksRUFBRSxRQUFRO2dCQUNkLFVBQVUsRUFBRTtvQkFDVixZQUFZLEVBQUUsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsRUFBRTtpQkFDM0Q7Z0JBQ0Qsb0JBQW9CLEVBQUUsS0FBSzthQUM1QjtTQUNGO0tBQ0Y7SUFDRCxNQUFNLENBQUMsT0FBTztRQUNaLE1BQU0sU0FBUyxHQUFHLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUE2QixDQUFDO1FBQ2pFLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxDQUFDLFNBQVMsRUFBRSxZQUFZLElBQUksRUFBRSxDQUFDLENBQUM7UUFDdkQsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZDLE1BQU0sU0FBUyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUMxQyxPQUFPLFFBQVEsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDaEMsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1lBQ0wsZ0JBQWdCLENBQUMsSUFBSTtnQkFDbkIsSUFBSSxTQUFTO29CQUFFLE9BQU87Z0JBQ3RCLElBQ0UsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssWUFBWTtvQkFDbkMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEtBQUssUUFBUTtvQkFDL0IsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssa0JBQWtCLEVBQ3ZDLENBQUM7b0JBQ0QsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQztvQkFDeEIsSUFDRSxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxZQUFZO3dCQUNsQyxHQUFHLENBQUMsUUFBUSxDQUFDLElBQUksS0FBSyxVQUFVO3dCQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxZQUFZO3dCQUNoQyxHQUFHLENBQUMsTUFBTSxDQUFDLElBQUksS0FBSyxRQUFRLEVBQzVCLENBQUM7d0JBQ0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLElBQUksRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztvQkFDL0MsQ0FBQztnQkFDSCxDQUFDO1lBQ0gsQ0FBQztTQUNGLENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQztBQUVGLGVBQWUsSUFBSSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gTW92ZWQgZnJvbSBwYWNrYWdlIHJvb3QgZXNsaW50LXJ1bGVzIGRpcmVjdG9yeSBpbnRvIHNyYyB0byBzYXRpc2Z5IFRTIHJvb3REaXJcbmltcG9ydCB0eXBlIHsgUnVsZSB9IGZyb20gJ2VzbGludCc7XG5cbmludGVyZmFjZSBPcHRpb25zU2hhcGUge1xuICBhbGxvd0luRmlsZXM/OiBzdHJpbmdbXTtcbn1cblxuY29uc3QgcnVsZTogUnVsZS5SdWxlTW9kdWxlID0ge1xuICBtZXRhOiB7XG4gICAgdHlwZTogJ3N1Z2dlc3Rpb24nLFxuICAgIGRvY3M6IHtcbiAgICAgIGRlc2NyaXB0aW9uOlxuICAgICAgICAnRGlzY291cmFnZSBkaXJlY3Qgd2luZG93LmxvY2F0aW9uLnNlYXJjaCBhY2Nlc3M7IHVzZSB1c2VRdWVyeSgpL3VzZVR5cGVkUXVlcnkoKSBpbnN0ZWFkJyxcbiAgICAgIHJlY29tbWVuZGVkOiBmYWxzZSxcbiAgICB9LFxuICAgIG1lc3NhZ2VzOiB7XG4gICAgICBhdm9pZDpcbiAgICAgICAgJ0F2b2lkIGRpcmVjdCBhY2Nlc3MgdG8gd2luZG93LmxvY2F0aW9uLnNlYXJjaC4gVXNlIHVzZVF1ZXJ5KCkgLyB1c2VUeXBlZFF1ZXJ5KCkgZnJvbSBAcGx1bWlsZS9yb3V0ZXIuJyxcbiAgICB9LFxuICAgIHNjaGVtYTogW1xuICAgICAge1xuICAgICAgICB0eXBlOiAnb2JqZWN0JyxcbiAgICAgICAgcHJvcGVydGllczoge1xuICAgICAgICAgIGFsbG93SW5GaWxlczogeyB0eXBlOiAnYXJyYXknLCBpdGVtczogeyB0eXBlOiAnc3RyaW5nJyB9IH0sXG4gICAgICAgIH0sXG4gICAgICAgIGFkZGl0aW9uYWxQcm9wZXJ0aWVzOiBmYWxzZSxcbiAgICAgIH0sXG4gICAgXSxcbiAgfSxcbiAgY3JlYXRlKGNvbnRleHQpIHtcbiAgICBjb25zdCByYXdPcHRpb24gPSBjb250ZXh0Lm9wdGlvbnNbMF0gYXMgT3B0aW9uc1NoYXBlIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IGFsbG93SW4gPSBuZXcgU2V0KHJhd09wdGlvbj8uYWxsb3dJbkZpbGVzID8/IFtdKTtcbiAgICBjb25zdCBmaWxlbmFtZSA9IGNvbnRleHQuZ2V0RmlsZW5hbWUoKTtcbiAgICBjb25zdCBpc0FsbG93ZWQgPSBbLi4uYWxsb3dJbl0uc29tZSgocGF0KSA9PiB7XG4gICAgICByZXR1cm4gZmlsZW5hbWUuaW5jbHVkZXMocGF0KTtcbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICBNZW1iZXJFeHByZXNzaW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKGlzQWxsb3dlZCkgcmV0dXJuO1xuICAgICAgICBpZiAoXG4gICAgICAgICAgbm9kZS5wcm9wZXJ0eS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICBub2RlLnByb3BlcnR5Lm5hbWUgPT09ICdzZWFyY2gnICYmXG4gICAgICAgICAgbm9kZS5vYmplY3QudHlwZSA9PT0gJ01lbWJlckV4cHJlc3Npb24nXG4gICAgICAgICkge1xuICAgICAgICAgIGNvbnN0IG9iaiA9IG5vZGUub2JqZWN0O1xuICAgICAgICAgIGlmIChcbiAgICAgICAgICAgIG9iai5wcm9wZXJ0eS50eXBlID09PSAnSWRlbnRpZmllcicgJiZcbiAgICAgICAgICAgIG9iai5wcm9wZXJ0eS5uYW1lID09PSAnbG9jYXRpb24nICYmXG4gICAgICAgICAgICBvYmoub2JqZWN0LnR5cGUgPT09ICdJZGVudGlmaWVyJyAmJlxuICAgICAgICAgICAgb2JqLm9iamVjdC5uYW1lID09PSAnd2luZG93J1xuICAgICAgICAgICkge1xuICAgICAgICAgICAgY29udGV4dC5yZXBvcnQoeyBub2RlLCBtZXNzYWdlSWQ6ICdhdm9pZCcgfSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9LFxuICAgIH07XG4gIH0sXG59O1xuXG5leHBvcnQgZGVmYXVsdCBydWxlO1xuIl19
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BrowserHistory.d.ts","sourceRoot":"","sources":["../../../src/history/BrowserHistory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQ5E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAI5D;AAOD,MAAM,CAAC,OAAO,OAAO,cAAe,YAAW,OAAO;IAEpD,OAAO,CAAC,WAAW,CAAyB;;IAe5C,IAAW,QAAQ,IAAI,QAAQ,
|
|
1
|
+
{"version":3,"file":"BrowserHistory.d.ts","sourceRoot":"","sources":["../../../src/history/BrowserHistory.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAQ5E,wBAAgB,UAAU,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,CAI5D;AAOD,MAAM,CAAC,OAAO,OAAO,cAAe,YAAW,OAAO;IAEpD,OAAO,CAAC,WAAW,CAAyB;;IAe5C,IAAW,QAAQ,IAAI,QAAQ,CAU9B;IAKM,IAAI,IAAI,IAAI;IAUZ,GAAG,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAapC,IAAI,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAYrC,WAAW,CAAC,QAAQ,EAAE,eAAe,GAAG,IAAI;IAY5C,SAAS,CAAC,QAAQ,EAAE,eAAe,GAAG,MAAM,IAAI;IAWvD,OAAO,CAAC,MAAM,CAOZ;IAOF,OAAO,CAAC,QAAQ,CAOd;IAKF,OAAO,CAAC,WAAW;CAGpB"}
|
|
@@ -9,7 +9,9 @@ export default class BrowserHistory {
|
|
|
9
9
|
}
|
|
10
10
|
get location() {
|
|
11
11
|
return {
|
|
12
|
-
|
|
12
|
+
pathname: window.location.pathname,
|
|
13
|
+
search: window.location.search,
|
|
14
|
+
hash: window.location.hash,
|
|
13
15
|
};
|
|
14
16
|
}
|
|
15
17
|
init() {
|
|
@@ -56,4 +58,4 @@ export default class BrowserHistory {
|
|
|
56
58
|
window.addEventListener('popstate', this.__fire);
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
61
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiQnJvd3Nlckhpc3RvcnkuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvaGlzdG9yeS9Ccm93c2VySGlzdG9yeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFRQSxNQUFNLFVBQVUsVUFBVSxDQUFDLFFBQXlCO0lBQ2xELE1BQU0sRUFBRSxRQUFRLEVBQUUsTUFBTSxHQUFHLEVBQUUsRUFBRSxJQUFJLEdBQUcsRUFBRSxFQUFFLEdBQUcsUUFBUSxDQUFDO0lBRXRELE9BQU8sR0FBRyxRQUFRLEdBQUcsTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ3ZDLENBQUM7QUFPRCxNQUFNLENBQUMsT0FBTyxPQUFPLGNBQWM7SUFFekIsV0FBVyxHQUFzQixFQUFFLENBQUM7SUFLNUM7UUFDRSxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDO0lBUUQsSUFBVyxRQUFRO1FBSWpCLE9BQU87WUFFTCxRQUFRLEVBQUUsTUFBTSxDQUFDLFFBQVEsQ0FBQyxRQUFRO1lBQ2xDLE1BQU0sRUFBRSxNQUFNLENBQUMsUUFBUSxDQUFDLE1BQU07WUFDOUIsSUFBSSxFQUFFLE1BQU0sQ0FBQyxRQUFRLENBQUMsSUFBSTtTQUNKLENBQUM7SUFDM0IsQ0FBQztJQUtNLElBQUk7UUFDVCxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7SUFDckIsQ0FBQztJQVFNLEdBQUcsQ0FBQyxRQUF5QjtRQUNsQyxNQUFNLElBQUksR0FBRyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7UUFFbEMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3RCLENBQUM7SUFRTSxJQUFJLENBQUMsUUFBeUI7UUFDbkMsTUFBTSxJQUFJLEdBQUcsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBRWxDLE1BQU0sQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFPTSxXQUFXLENBQUMsUUFBeUI7UUFDMUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xELE9BQU8sSUFBSSxLQUFLLFFBQVEsQ0FBQztRQUMzQixDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7SUFRTSxTQUFTLENBQUMsUUFBeUI7UUFDeEMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDaEMsT0FBTyxHQUFHLEVBQUU7WUFDVixJQUFJLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQztJQUNKLENBQUM7SUFNTyxNQUFNLEdBQUcsR0FBUyxFQUFFO1FBQzFCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDZCxNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDO1lBQzFCLElBQUksQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7Z0JBQ3BDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDNUIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDUixDQUFDLENBQUM7SUFPTSxRQUFRLEdBQUcsQ0FBQyxhQUFhLEdBQUcsS0FBSyxFQUFFLEVBQUU7UUFDM0MsVUFBVSxDQUFDLEdBQUcsRUFBRTtZQUNkLE1BQU0sRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUM7WUFDMUIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDcEMsUUFBUSxDQUFDLFFBQVEsRUFBRSxhQUFhLENBQUMsQ0FBQztZQUNwQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNSLENBQUMsQ0FBQztJQUtNLFdBQVc7UUFDakIsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDbkQsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHR5cGUgeyBIaXN0b3J5LCBIaXN0b3J5TGlzdGVuZXIsIEhpc3RvcnlMb2NhdGlvbiB9IGZyb20gJy4vdHlwZXMuanMnO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBjb21wbGV0ZSBVUkwgcGF0aCBmcm9tIGEgSGlzdG9yeUxvY2F0aW9uIG9iamVjdC5cbiAqXG4gKiBAcGFyYW0gbG9jYXRpb24gLSBMb2NhdGlvbiBvYmplY3QgY29udGFpbmluZyBwYXRobmFtZSwgc2VhcmNoLCBhbmQgaGFzaFxuICogQHJldHVybnMgQ29tcGxldGUgcGF0aCBzdHJpbmcgY29tYmluaW5nIGFsbCBjb21wb25lbnRzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQYXRoKGxvY2F0aW9uOiBIaXN0b3J5TG9jYXRpb24pOiBzdHJpbmcge1xuICBjb25zdCB7IHBhdGhuYW1lLCBzZWFyY2ggPSAnJywgaGFzaCA9ICcnIH0gPSBsb2NhdGlvbjtcblxuICByZXR1cm4gYCR7cGF0aG5hbWV9JHtzZWFyY2h9JHtoYXNofWA7XG59XG5cbi8qKlxuICogQnJvd3NlciBoaXN0b3J5IGltcGxlbWVudGF0aW9uIHVzaW5nIHRoZSBIVE1MNSBIaXN0b3J5IEFQSS5cbiAqIE1hbmFnZXMgYnJvd3NlciBuYXZpZ2F0aW9uIHN0YXRlIGFuZCBwcm92aWRlcyBhIGNvbnNpc3RlbnQgaW50ZXJmYWNlXG4gKiBmb3IgcHJvZ3JhbW1hdGljIG5hdmlnYXRpb24gYW5kIGxvY2F0aW9uIGNoYW5nZSBub3RpZmljYXRpb25zLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCcm93c2VySGlzdG9yeSBpbXBsZW1lbnRzIEhpc3Rvcnkge1xuICAvKiogQXJyYXkgb2YgbGlzdGVuZXJzIGZvciBsb2NhdGlvbiBjaGFuZ2VzICovXG4gIHByaXZhdGUgX19saXN0ZW5lcnM6IEhpc3RvcnlMaXN0ZW5lcltdID0gW107XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBuZXcgQnJvd3Nlckhpc3RvcnkgaW5zdGFuY2UgYW5kIGluaXRpYWxpemVzIGV2ZW50IGxpc3RlbmVycy5cbiAgICovXG4gIHB1YmxpYyBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmluaXQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSBjdXJyZW50IGJyb3dzZXIgbG9jYXRpb24uXG4gICAqXG4gICAqIEByZXR1cm5zIEN1cnJlbnQgd2luZG93LmxvY2F0aW9uIG9iamVjdFxuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIGNsYXNzLW1ldGhvZHMtdXNlLXRoaXNcbiAgcHVibGljIGdldCBsb2NhdGlvbigpOiBMb2NhdGlvbiB7XG4gICAgLy8gU29tZSB0ZXN0IERPTSBlbnZpcm9ubWVudHMgKGUuZy4gaGFwcHktZG9tKSBleHBvc2Ugbm9uLWVudW1lcmFibGVcbiAgICAvLyBMb2NhdGlvbiBwcm9wZXJ0aWVzIHNvIGEgc2ltcGxlIHNwcmVhZCByZXR1cm5zIGFuIGVtcHR5IG9iamVjdC5cbiAgICAvLyBSZXR1cm4gYW4gZXhwbGljaXQgcGxhaW4gb2JqZWN0IHdpdGggdGhlIGZpZWxkcyB3ZSByZWx5IG9uLlxuICAgIHJldHVybiB7XG4gICAgICAvLyBwYXRobmFtZS9zZWFyY2gvaGFzaCBhcmUgc3VmZmljaWVudCBmb3Igb3VyIHJvdXRlciBsb2dpY1xuICAgICAgcGF0aG5hbWU6IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSxcbiAgICAgIHNlYXJjaDogd2luZG93LmxvY2F0aW9uLnNlYXJjaCxcbiAgICAgIGhhc2g6IHdpbmRvdy5sb2NhdGlvbi5oYXNoLFxuICAgIH0gYXMgdW5rbm93biBhcyBMb2NhdGlvbjtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXplcyB0aGUgaGlzdG9yeSBpbnN0YW5jZSBieSBzZXR0aW5nIHVwIGV2ZW50IGxpc3RlbmVycy5cbiAgICovXG4gIHB1YmxpYyBpbml0KCk6IHZvaWQge1xuICAgIHRoaXMuX19zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyB0aGUgY3VycmVudCBoaXN0b3J5IGVudHJ5IHdpdGggYSBuZXcgbG9jYXRpb24uXG4gICAqIFRoaXMgdXBkYXRlcyB0aGUgVVJMIHdpdGhvdXQgY3JlYXRpbmcgYSBuZXcgaGlzdG9yeSBlbnRyeS5cbiAgICpcbiAgICogQHBhcmFtIGxvY2F0aW9uIC0gTmV3IGxvY2F0aW9uIHRvIHNldFxuICAgKi9cbiAgcHVibGljIHNldChsb2NhdGlvbjogSGlzdG9yeUxvY2F0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgcGF0aCA9IGNyZWF0ZVBhdGgobG9jYXRpb24pO1xuXG4gICAgd2luZG93Lmhpc3RvcnkucmVwbGFjZVN0YXRlKHt9LCAnJywgcGF0aCk7XG4gICAgdGhpcy5fX2RvRmlyZSh0cnVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOYXZpZ2F0ZXMgdG8gYSBuZXcgbG9jYXRpb24gYnkgcHVzaGluZyBhIG5ldyBoaXN0b3J5IGVudHJ5LlxuICAgKiBUaGlzIGNyZWF0ZXMgYSBuZXcgZW50cnkgaW4gdGhlIGJyb3dzZXIncyBoaXN0b3J5IHN0YWNrLlxuICAgKlxuICAgKiBAcGFyYW0gbG9jYXRpb24gLSBMb2NhdGlvbiB0byBuYXZpZ2F0ZSB0b1xuICAgKi9cbiAgcHVibGljIHB1c2gobG9jYXRpb246IEhpc3RvcnlMb2NhdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IHBhdGggPSBjcmVhdGVQYXRoKGxvY2F0aW9uKTtcblxuICAgIHdpbmRvdy5oaXN0b3J5LnB1c2hTdGF0ZSh7fSwgJycsIHBhdGgpO1xuICAgIHRoaXMuX19maXJlKCk7XG4gIH1cblxuICAvKipcbiAgICogUmVtb3ZlcyBhIGxpc3RlbmVyIGZyb20gdGhlIGhpc3RvcnkgY2hhbmdlIG5vdGlmaWNhdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBsaXN0ZW5lciAtIExpc3RlbmVyIGZ1bmN0aW9uIHRvIHJlbW92ZVxuICAgKi9cbiAgcHVibGljIHVuc3Vic2NyaWJlKGxpc3RlbmVyOiBIaXN0b3J5TGlzdGVuZXIpOiB2b2lkIHtcbiAgICB0aGlzLl9fbGlzdGVuZXJzID0gdGhpcy5fX2xpc3RlbmVycy5maWx0ZXIoKGl0ZW0pID0+IHtcbiAgICAgIHJldHVybiBpdGVtICE9PSBsaXN0ZW5lcjtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdWJzY3JpYmVzIHRvIGhpc3RvcnkgY2hhbmdlcy5cbiAgICpcbiAgICogQHBhcmFtIGxpc3RlbmVyIC0gRnVuY3Rpb24gdG8gY2FsbCB3aGVuIGxvY2F0aW9uIGNoYW5nZXNcbiAgICogQHJldHVybnMgVW5zdWJzY3JpYmUgZnVuY3Rpb25cbiAgICovXG4gIHB1YmxpYyBzdWJzY3JpYmUobGlzdGVuZXI6IEhpc3RvcnlMaXN0ZW5lcik6ICgpID0+IHZvaWQge1xuICAgIHRoaXMuX19saXN0ZW5lcnMucHVzaChsaXN0ZW5lcik7XG4gICAgcmV0dXJuICgpID0+IHtcbiAgICAgIHRoaXMudW5zdWJzY3JpYmUobGlzdGVuZXIpO1xuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogTm90aWZpZXMgYWxsIGxpc3RlbmVycyBvZiBhIGxvY2F0aW9uIGNoYW5nZS5cbiAgICogVXNlcyBzZXRUaW1lb3V0IHRvIGVuc3VyZSB0aGUgbm90aWZpY2F0aW9uIGhhcHBlbnMgYWZ0ZXIgdGhlIGN1cnJlbnQgZXhlY3V0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfX2ZpcmUgPSAoKTogdm9pZCA9PiB7XG4gICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICBjb25zdCB7IGxvY2F0aW9uIH0gPSB0aGlzO1xuICAgICAgdGhpcy5fX2xpc3RlbmVycy5mb3JFYWNoKChsaXN0ZW5lcikgPT4ge1xuICAgICAgICBsaXN0ZW5lcihsb2NhdGlvbiwgZmFsc2UpO1xuICAgICAgfSk7XG4gICAgfSwgMCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIE5vdGlmaWVzIGFsbCBsaXN0ZW5lcnMgb2YgYSBsb2NhdGlvbiBjaGFuZ2Ugd2l0aCBvcHRpb25hbCBmb3JjZSByZXJlbmRlci5cbiAgICpcbiAgICogQHBhcmFtIGZvcmNlUmVyZW5kZXIgLSBXaGV0aGVyIHRvIGZvcmNlIGEgcmUtcmVuZGVyXG4gICAqL1xuICBwcml2YXRlIF9fZG9GaXJlID0gKGZvcmNlUmVyZW5kZXIgPSBmYWxzZSkgPT4ge1xuICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgY29uc3QgeyBsb2NhdGlvbiB9ID0gdGhpcztcbiAgICAgIHRoaXMuX19saXN0ZW5lcnMuZm9yRWFjaCgobGlzdGVuZXIpID0+IHtcbiAgICAgICAgbGlzdGVuZXIobG9jYXRpb24sIGZvcmNlUmVyZW5kZXIpO1xuICAgICAgfSk7XG4gICAgfSwgMCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIFNldHMgdXAgdGhlIHBvcHN0YXRlIGV2ZW50IGxpc3RlbmVyIGZvciBicm93c2VyIGJhY2svZm9yd2FyZCBuYXZpZ2F0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfX3N1YnNjcmliZSgpIHtcbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCB0aGlzLl9fZmlyZSk7XG4gIH1cbn1cbiJdfQ==
|
package/lib/esm/index.d.ts
CHANGED
package/lib/esm/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,cAAc,CAAC;AAG7B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AACA,cAAc,mBAAmB,CAAC;AAGlC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,cAAc,CAAC;AAG7B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,CAAC,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAG1D,mBAAmB,YAAY,CAAC"}
|
package/lib/esm/index.js
CHANGED
|
@@ -4,4 +4,5 @@ export * from './routing/index.js';
|
|
|
4
4
|
export * from './builder.js';
|
|
5
5
|
export * from './ResourcePage.js';
|
|
6
6
|
export * from './tools.js';
|
|
7
|
-
|
|
7
|
+
export { q, parseTypedQuery } from './tools/query-dsl.js';
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsY0FBYyxtQkFBbUIsQ0FBQztBQUdsQyxjQUFjLG9CQUFvQixDQUFDO0FBR25DLGNBQWMsb0JBQW9CLENBQUM7QUFHbkMsY0FBYyxjQUFjLENBQUM7QUFHN0IsY0FBYyxtQkFBbUIsQ0FBQztBQUdsQyxjQUFjLFlBQVksQ0FBQztBQUMzQixPQUFPLEVBQUUsQ0FBQyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gRXhwb3J0IGVycm9yIGhhbmRsaW5nIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9lcnJvcnMvaW5kZXguanMnO1xuXG4vLyBFeHBvcnQgYnJvd3NlciBoaXN0b3J5IG1hbmFnZW1lbnRcbmV4cG9ydCAqIGZyb20gJy4vaGlzdG9yeS9pbmRleC5qcyc7XG5cbi8vIEV4cG9ydCByb3V0aW5nIGNvbXBvbmVudHMgYW5kIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9yb3V0aW5nL2luZGV4LmpzJztcblxuLy8gRXhwb3J0IHJvdXRlIGJ1aWxkaW5nIHV0aWxpdGllc1xuZXhwb3J0ICogZnJvbSAnLi9idWlsZGVyLmpzJztcblxuLy8gRXhwb3J0IHJlc291cmNlIHBhZ2UgbWFuYWdlbWVudCBmb3IgbGF6eSBsb2FkaW5nXG5leHBvcnQgKiBmcm9tICcuL1Jlc291cmNlUGFnZS5qcyc7XG5cbi8vIEV4cG9ydCB1dGlsaXR5IGZ1bmN0aW9uc1xuZXhwb3J0ICogZnJvbSAnLi90b29scy5qcyc7XG5leHBvcnQgeyBxLCBwYXJzZVR5cGVkUXVlcnkgfSBmcm9tICcuL3Rvb2xzL3F1ZXJ5LWRzbC5qcyc7XG5cbi8vIEV4cG9ydCBhbGwgVHlwZVNjcmlwdCB0eXBlc1xuZXhwb3J0IHR5cGUgKiBmcm9tICcuL3R5cGVzLmpzJztcbiJdfQ==
|
|
@@ -15,6 +15,7 @@ type Props = {
|
|
|
15
15
|
onMouseOver?: React.MouseEventHandler<HTMLAnchorElement>;
|
|
16
16
|
target?: HTMLAttributeAnchorTarget;
|
|
17
17
|
to?: HistoryLocation | string;
|
|
18
|
+
query?: Record<string, any>;
|
|
18
19
|
};
|
|
19
20
|
declare const Link: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLAnchorElement>>;
|
|
20
21
|
export default Link;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/routing/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,yBAAyB,EAE9B,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"Link.d.ts","sourceRoot":"","sources":["../../../src/routing/Link.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EACZ,KAAK,yBAAyB,EAE9B,KAAK,SAAS,EAIf,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAY3E,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,OAAO,EACd,OAAO,EAAE,cAAc,GAAG,SAAS,EACnC,QAAQ,EAAE,MAAM,GACf,OAAO,CAmBT;AAKD,KAAK,KAAK,GAAG;IAEX,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,QAAQ,EAAE,SAAS,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAE9B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAE7B,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAErD,OAAO,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAErD,WAAW,CAAC,EAAE,KAAK,CAAC,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAEzD,MAAM,CAAC,EAAE,yBAAyB,CAAC;IAEnC,EAAE,CAAC,EAAE,eAAe,GAAG,MAAM,CAAC;IAE9B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B,CAAC;AAyBF,QAAA,MAAM,IAAI,iFA2KR,CAAC;AAEH,eAAe,IAAI,CAAC"}
|