@richie-router/react 0.0.1 → 0.1.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.
@@ -0,0 +1,19 @@
1
+ export interface HistoryLocation {
2
+ href: string;
3
+ pathname: string;
4
+ search: string;
5
+ hash: string;
6
+ state: unknown;
7
+ }
8
+ export interface RouterHistory {
9
+ readonly location: HistoryLocation;
10
+ listen(listener: () => void): () => void;
11
+ push(href: string, state?: unknown): void;
12
+ replace(href: string, state?: unknown): void;
13
+ }
14
+ export declare function createBrowserHistory(): RouterHistory;
15
+ export declare function createHashHistory(): RouterHistory;
16
+ export interface MemoryHistoryOptions {
17
+ initialEntries?: string[];
18
+ }
19
+ export declare function createMemoryHistory(options?: MemoryHistoryOptions): RouterHistory;
@@ -0,0 +1,2 @@
1
+ export * from './history';
2
+ export * from './router';
@@ -0,0 +1,263 @@
1
+ import React from 'react';
2
+ import { RouteNode, isNotFound, isRedirect, notFound, redirect } from '@richie-router/core';
3
+ import type { AnyComponent, AnyRoute, DehydratedHeadState, HeadConfig, NormalizeRouteId, ParsedLocation, ResolveAllParams, RouteMatch, RouteOptions as CoreRouteOptions } from '@richie-router/core';
4
+ import { createBrowserHistory, createHashHistory, createMemoryHistory } from './history';
5
+ import type { MemoryHistoryOptions, RouterHistory } from './history';
6
+ declare global {
7
+ interface Window {
8
+ __RICHIE_ROUTER_HEAD__?: DehydratedHeadState;
9
+ }
10
+ }
11
+ export interface Register {
12
+ }
13
+ type RegisteredRouteSearchSchema = Register extends {
14
+ routeSearchSchema: infer TRouteSearchSchema;
15
+ } ? TRouteSearchSchema : Record<string, {}>;
16
+ type RegisteredRouteTree = Register extends {
17
+ routeTree: infer TRouteTree;
18
+ } ? TRouteTree : AnyRoute;
19
+ interface DefaultFileTypes {
20
+ fullPaths: string;
21
+ to: string;
22
+ id: string;
23
+ fileRoutesById: Record<string, AnyRoute>;
24
+ fileRoutesByTo: Record<string, AnyRoute>;
25
+ fileRoutesByFullPath: Record<string, AnyRoute>;
26
+ }
27
+ type RegisteredFileTypes = RegisteredRouteTree extends {
28
+ __fileTypes: infer TFileTypes;
29
+ } ? TFileTypes : DefaultFileTypes;
30
+ type RegisteredRoutesByTo = RegisteredFileTypes extends {
31
+ fileRoutesByTo: infer TRoutesByTo;
32
+ } ? TRoutesByTo : Record<string, AnyRoute>;
33
+ export type RegisteredRouter = Register extends {
34
+ router: infer TRouter;
35
+ } ? TRouter : Router<AnyRoute>;
36
+ export type RoutePaths = RegisteredFileTypes extends {
37
+ to: infer TTo;
38
+ } ? TTo & string : string;
39
+ export type RouteById<TPath extends string> = TPath extends keyof RegisteredRoutesByTo ? RegisteredRoutesByTo[TPath] : never;
40
+ type ParamsOfRoute<TRoute> = TRoute extends {
41
+ types: {
42
+ params: infer TParams;
43
+ };
44
+ } ? TParams : Record<string, string>;
45
+ type SearchOfRoute<TRoute> = TRoute extends {
46
+ types: {
47
+ search: infer TSearch;
48
+ };
49
+ } ? TSearch : unknown;
50
+ type MatchOfRoute<TRoute> = {
51
+ id: string;
52
+ pathname: string;
53
+ params: ParamsOfRoute<TRoute>;
54
+ route: TRoute;
55
+ search: SearchOfRoute<TRoute>;
56
+ to: TRoute extends {
57
+ types: {
58
+ to: infer TTo;
59
+ };
60
+ } ? TTo : string;
61
+ };
62
+ type SafeRouteByTo<TTo extends string> = [RouteById<TTo>] extends [never] ? AnyRoute : RouteById<TTo>;
63
+ type ParamsForTo<TTo extends string> = ParamsOfRoute<SafeRouteByTo<TTo>>;
64
+ type SearchForTo<TTo extends string> = SearchOfRoute<SafeRouteByTo<TTo>>;
65
+ type SearchForRouteId<TPath extends string> = TPath extends keyof RegisteredRouteSearchSchema ? RegisteredRouteSearchSchema[TPath] : {};
66
+ type ParamsInput<TParams> = TParams | ((previous: TParams) => TParams);
67
+ type SearchInput<TSearch> = TSearch | ((previous: TSearch) => TSearch) | true;
68
+ type ParamsOption<TParams> = keyof TParams extends never ? {
69
+ params?: never;
70
+ } : {
71
+ params: ParamsInput<TParams>;
72
+ };
73
+ type ClientHeadOption<TPath extends string, TSearch> = HeadConfig | ((ctx: {
74
+ params: ResolveAllParams<TPath>;
75
+ search: TSearch;
76
+ matches: RouteMatch[];
77
+ }) => HeadConfig);
78
+ type RouteOptionsInput<TPath extends string, TSearch> = Omit<CoreRouteOptions<TPath, TSearch>, 'head'> & {
79
+ head?: ClientHeadOption<TPath, TSearch>;
80
+ };
81
+ type FileRouteInstance<TPath extends string, TSearch, TFileTypes = unknown, THasInlineHead extends boolean = boolean> = RouteNode<TPath, NormalizeRouteId<TPath>, ResolveAllParams<TPath>, TSearch, TFileTypes> & RouteApiMethods<RouteNode<TPath, NormalizeRouteId<TPath>, ResolveAllParams<TPath>, TSearch, TFileTypes>> & {
82
+ __hasInlineHead: THasInlineHead;
83
+ };
84
+ export interface TypedRouteMatch<TPath extends string, TSearch, TRoute extends AnyRoute = AnyRoute> extends Omit<RouteMatch<TRoute>, 'params' | 'search'> {
85
+ params: ResolveAllParams<TPath>;
86
+ search: TSearch;
87
+ }
88
+ interface RouteApiMethods<TRoute extends AnyRoute> {
89
+ useParams(): ParamsOfRoute<TRoute>;
90
+ useSearch(): SearchOfRoute<TRoute>;
91
+ useNavigate(): NavigateFn;
92
+ useMatch(): MatchOfRoute<TRoute>;
93
+ }
94
+ export interface NavigateBaseOptions {
95
+ from?: RoutePaths;
96
+ hash?: string;
97
+ replace?: boolean;
98
+ resetScroll?: boolean;
99
+ state?: Record<string, unknown>;
100
+ mask?: {
101
+ to: string;
102
+ };
103
+ ignoreBlocker?: boolean;
104
+ }
105
+ export type NavigateOptions<TTo extends RoutePaths = RoutePaths> = {
106
+ to: TTo;
107
+ search?: SearchInput<SearchForTo<TTo>>;
108
+ } & NavigateBaseOptions & ParamsOption<ParamsForTo<TTo>>;
109
+ export type NavigateFn = <TTo extends RoutePaths>(options: NavigateOptions<TTo>) => Promise<void>;
110
+ export type LinkOwnProps<TTo extends RoutePaths> = NavigateOptions<TTo> & {
111
+ preload?: 'intent' | 'render' | false;
112
+ activeProps?: React.AnchorHTMLAttributes<HTMLAnchorElement>;
113
+ children?: React.ReactNode | ((ctx: {
114
+ isActive: boolean;
115
+ }) => React.ReactNode);
116
+ };
117
+ export type LinkProps<TTo extends RoutePaths = RoutePaths> = LinkOwnProps<TTo> & Omit<React.AnchorHTMLAttributes<HTMLAnchorElement>, keyof LinkOwnProps<TTo> | 'href'>;
118
+ export interface RouterState {
119
+ status: 'idle' | 'loading';
120
+ location: ParsedLocation;
121
+ matches: RouteMatch[];
122
+ head: HeadConfig;
123
+ error: unknown;
124
+ }
125
+ export interface RouterOptions<TRouteTree extends AnyRoute> {
126
+ routeTree: TRouteTree;
127
+ history?: RouterHistory;
128
+ defaultPreload?: 'intent' | 'render' | false;
129
+ defaultPreloadDelay?: number;
130
+ defaultPendingMs?: number;
131
+ defaultPendingMinMs?: number;
132
+ defaultNotFoundComponent?: AnyComponent;
133
+ defaultErrorComponent?: AnyComponent;
134
+ scrollRestoration?: boolean;
135
+ scrollToTopSelectors?: string[];
136
+ headBasePath?: string;
137
+ trailingSlash?: 'always' | 'never' | 'preserve';
138
+ parseSearch?: (searchStr: string) => Record<string, unknown>;
139
+ stringifySearch?: (search: Record<string, unknown>) => string;
140
+ loadRouteHead?: (ctx: {
141
+ route: AnyRoute;
142
+ routeId: string;
143
+ params: Record<string, string>;
144
+ search: unknown;
145
+ location: ParsedLocation;
146
+ request?: Request;
147
+ }) => Promise<{
148
+ head: HeadConfig;
149
+ staleTime?: number;
150
+ }>;
151
+ }
152
+ type InternalRouteMatch = RouteMatch & {
153
+ id: string;
154
+ };
155
+ type Selector<TSelection> = (state: RouterState) => TSelection;
156
+ export declare function createFileRoute<TPath extends string>(path: TPath): <TOptions extends RouteOptionsInput<TPath, SearchForRouteId<TPath>>>(options: TOptions) => FileRouteInstance<TPath, SearchForRouteId<TPath>, unknown, TOptions extends {
157
+ head: any;
158
+ } ? true : false>;
159
+ export declare function createRootRoute<TOptions extends RouteOptionsInput<'__root__', SearchForRouteId<'__root__'>>>(options: TOptions): FileRouteInstance<'__root__', SearchForRouteId<'__root__'>, unknown, TOptions extends {
160
+ head: any;
161
+ } ? true : false>;
162
+ export declare class Router<TRouteTree extends AnyRoute> {
163
+ readonly routeTree: TRouteTree;
164
+ readonly history: RouterHistory;
165
+ readonly options: RouterOptions<TRouteTree>;
166
+ state: RouterState;
167
+ readonly routesByFullPath: Map<string, AnyRoute>;
168
+ readonly routesByTo: Map<string, AnyRoute>;
169
+ private readonly listeners;
170
+ private readonly headCache;
171
+ private readonly parseSearch;
172
+ private readonly stringifySearch;
173
+ private started;
174
+ private unsubscribeHistory?;
175
+ constructor(options: RouterOptions<TRouteTree>);
176
+ getSnapshot: () => RouterState;
177
+ subscribe: (listener: () => void) => (() => void);
178
+ start(): void;
179
+ dispose(): void;
180
+ load(options?: {
181
+ request?: Request;
182
+ }): Promise<void>;
183
+ navigate<TTo extends RoutePaths>(options: NavigateOptions<TTo>): Promise<void>;
184
+ preloadRoute<TTo extends RoutePaths>(options: NavigateOptions<TTo>): Promise<void>;
185
+ invalidate(): Promise<void>;
186
+ buildHref<TTo extends RoutePaths>(options: NavigateOptions<TTo>): string;
187
+ private readLocation;
188
+ private applyTrailingSlash;
189
+ private notify;
190
+ private findMatchByTo;
191
+ buildMatches(location: ParsedLocation): InternalRouteMatch[];
192
+ private resolveSearch;
193
+ resolveLocation(location: ParsedLocation, options?: {
194
+ request?: Request;
195
+ }): Promise<{
196
+ matches: InternalRouteMatch[];
197
+ head: HeadConfig;
198
+ error: unknown;
199
+ }>;
200
+ private resolveLocationHead;
201
+ private loadRouteHead;
202
+ private fetchRouteHead;
203
+ private commitLocation;
204
+ private restoreScroll;
205
+ private handleHistoryChange;
206
+ }
207
+ export declare function createRouter<TRouteTree extends AnyRoute>(options: RouterOptions<TRouteTree>): Router<TRouteTree>;
208
+ export declare function RouterProvider({ router }: {
209
+ router: RegisteredRouter;
210
+ }): React.ReactElement;
211
+ export declare function Outlet(): React.ReactNode;
212
+ export declare function useRouter(): RegisteredRouter;
213
+ export declare function useMatches(): RouteMatch[];
214
+ export declare function useMatch<TFrom extends RoutePaths>(options?: {
215
+ from?: TFrom;
216
+ }): MatchOfRoute<RouteById<TFrom>>;
217
+ export declare function useParams<TFrom extends RoutePaths>(options?: {
218
+ from?: TFrom;
219
+ }): ParamsOfRoute<RouteById<TFrom>>;
220
+ export declare function useSearch<TFrom extends RoutePaths>(options?: {
221
+ from?: TFrom;
222
+ }): SearchOfRoute<RouteById<TFrom>>;
223
+ export declare function useNavigate(): NavigateFn;
224
+ export declare function useLocation(): ParsedLocation;
225
+ export declare function useRouterState<TSelection>(options: {
226
+ select: Selector<TSelection>;
227
+ }): TSelection;
228
+ export interface BlockerState {
229
+ status: 'idle' | 'blocked';
230
+ next: ParsedLocation | null;
231
+ proceed(): void;
232
+ reset(): void;
233
+ }
234
+ export declare function useBlocker(options: {
235
+ shouldBlockFn?: (ctx: {
236
+ current: ParsedLocation;
237
+ next: ParsedLocation | null;
238
+ }) => boolean;
239
+ withResolver?: boolean;
240
+ enableBeforeUnload?: boolean;
241
+ }): BlockerState;
242
+ export declare function Block(): null;
243
+ export declare function useElementScrollRestoration(): {
244
+ ref: React.RefCallback<HTMLElement>;
245
+ };
246
+ export declare const Link: <TTo extends RoutePaths>(props: LinkProps<TTo> & {
247
+ ref?: React.Ref<HTMLAnchorElement>;
248
+ }) => React.ReactElement;
249
+ export declare function createLink<TProps extends {
250
+ href?: string;
251
+ children?: React.ReactNode;
252
+ }>(Component: React.ComponentType<TProps>): <TTo extends RoutePaths>(props: LinkProps<TTo> & Omit<TProps, keyof LinkProps<TTo>>) => React.ReactElement;
253
+ export declare function linkOptions<TTo extends RoutePaths>(options: NavigateOptions<TTo>): NavigateOptions<TTo>;
254
+ export declare function getRouteApi<TTo extends RoutePaths>(to: TTo): {
255
+ useParams: () => ParamsOfRoute<RouteById<TTo>>;
256
+ useSearch: () => SearchOfRoute<RouteById<TTo>>;
257
+ useMatch: () => MatchOfRoute<RouteById<TTo>>;
258
+ };
259
+ export declare function createRouteMask<TMask extends {
260
+ to: string;
261
+ }>(mask: TMask): TMask;
262
+ export { redirect, notFound, isRedirect, isNotFound, createBrowserHistory, createHashHistory, createMemoryHistory, };
263
+ export type { MemoryHistoryOptions };
package/package.json CHANGED
@@ -1,10 +1,49 @@
1
1
  {
2
2
  "name": "@richie-router/react",
3
- "version": "0.0.1",
4
- "description": "OIDC trusted publishing setup package for @richie-router/react",
3
+ "version": "0.1.2",
4
+ "description": "React runtime, components, and hooks for Richie Router",
5
+ "sideEffects": false,
6
+ "exports": {
7
+ "./package.json": "./package.json",
8
+ ".": {
9
+ "types": "./dist/types/index.d.ts",
10
+ "import": "./dist/esm/index.mjs",
11
+ "require": "./dist/cjs/index.cjs",
12
+ "default": "./dist/esm/index.mjs"
13
+ }
14
+ },
15
+ "dependencies": {
16
+ "@richie-router/core": "^0.1.2"
17
+ },
18
+ "peerDependencies": {
19
+ "react": "^19"
20
+ },
21
+ "author": "Richie <oss@ricsam.dev>",
22
+ "homepage": "https://docs.ricsam.dev/richie-router",
23
+ "bugs": {
24
+ "url": "https://github.com/ricsam/richie-router/issues"
25
+ },
5
26
  "keywords": [
6
- "oidc",
7
- "trusted-publishing",
8
- "setup"
9
- ]
10
- }
27
+ "router",
28
+ "react",
29
+ "typescript",
30
+ "bun",
31
+ "file-based-routing",
32
+ "type-safe"
33
+ ],
34
+ "repository": {
35
+ "type": "git",
36
+ "url": "git+https://github.com/ricsam/richie-router.git",
37
+ "directory": "packages/react"
38
+ },
39
+ "main": "./dist/cjs/index.cjs",
40
+ "module": "./dist/esm/index.mjs",
41
+ "types": "./dist/types/index.d.ts",
42
+ "files": [
43
+ "dist"
44
+ ],
45
+ "publishConfig": {
46
+ "access": "public",
47
+ "provenance": true
48
+ }
49
+ }
package/README.md DELETED
@@ -1,45 +0,0 @@
1
- # @richie-router/react
2
-
3
- ## ⚠️ IMPORTANT NOTICE ⚠️
4
-
5
- **This package is created solely for the purpose of setting up OIDC (OpenID Connect) trusted publishing with npm.**
6
-
7
- This is **NOT** a functional package and contains **NO** code or functionality beyond the OIDC setup configuration.
8
-
9
- ## Purpose
10
-
11
- This package exists to:
12
- 1. Configure OIDC trusted publishing for the package name `@richie-router/react`
13
- 2. Enable secure, token-less publishing from CI/CD workflows
14
- 3. Establish provenance for packages published under this name
15
-
16
- ## What is OIDC Trusted Publishing?
17
-
18
- OIDC trusted publishing allows package maintainers to publish packages directly from their CI/CD workflows without needing to manage npm access tokens. Instead, it uses OpenID Connect to establish trust between the CI/CD provider (like GitHub Actions) and npm.
19
-
20
- ## Setup Instructions
21
-
22
- To properly configure OIDC trusted publishing for this package:
23
-
24
- 1. Go to [npmjs.com](https://www.npmjs.com/) and navigate to your package settings
25
- 2. Configure the trusted publisher (e.g., GitHub Actions)
26
- 3. Specify the repository and workflow that should be allowed to publish
27
- 4. Use the configured workflow to publish your actual package
28
-
29
- ## DO NOT USE THIS PACKAGE
30
-
31
- This package is a placeholder for OIDC configuration only. It:
32
- - Contains no executable code
33
- - Provides no functionality
34
- - Should not be installed as a dependency
35
- - Exists only for administrative purposes
36
-
37
- ## More Information
38
-
39
- For more details about npm's trusted publishing feature, see:
40
- - [npm Trusted Publishing Documentation](https://docs.npmjs.com/generating-provenance-statements)
41
- - [GitHub Actions OIDC Documentation](https://docs.github.com/en/actions/deployment/security-hardening-your-deployments/about-security-hardening-with-openid-connect)
42
-
43
- ---
44
-
45
- **Maintained for OIDC setup purposes only**