@zap-js/client 0.0.2 → 0.0.5
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 +310 -24
- package/bin/zap +0 -0
- package/bin/zap-codegen +0 -0
- package/dist/cli/commands/build.d.ts +11 -0
- package/dist/cli/commands/build.js +282 -0
- package/dist/cli/commands/codegen.d.ts +8 -0
- package/dist/cli/commands/codegen.js +95 -0
- package/dist/cli/commands/dev.d.ts +20 -0
- package/dist/cli/commands/dev.js +78 -0
- package/dist/cli/commands/new.d.ts +9 -0
- package/dist/cli/commands/new.js +307 -0
- package/dist/cli/commands/routes-old.d.ts +9 -0
- package/dist/cli/commands/routes-old.js +106 -0
- package/dist/cli/commands/routes.d.ts +11 -0
- package/dist/cli/commands/routes.js +280 -0
- package/dist/cli/commands/serve.d.ts +17 -0
- package/dist/cli/commands/serve.js +386 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +76 -0
- package/dist/cli/utils/index.d.ts +2 -0
- package/dist/cli/utils/index.js +2 -0
- package/dist/cli/utils/logger.d.ts +84 -0
- package/dist/cli/utils/logger.js +181 -0
- package/dist/cli/utils/port-finder.d.ts +8 -0
- package/dist/cli/utils/port-finder.js +48 -0
- package/dist/dev-server/codegen-runner.d.ts +41 -0
- package/dist/dev-server/codegen-runner.js +172 -0
- package/dist/dev-server/hot-reload.d.ts +72 -0
- package/dist/dev-server/hot-reload.js +280 -0
- package/dist/dev-server/index.d.ts +8 -0
- package/dist/dev-server/index.js +8 -0
- package/dist/dev-server/route-scanner.d.ts +84 -0
- package/dist/dev-server/route-scanner.js +113 -0
- package/dist/dev-server/rust-builder.d.ts +66 -0
- package/dist/dev-server/rust-builder.js +286 -0
- package/dist/dev-server/server.d.ts +147 -0
- package/dist/dev-server/server.js +660 -0
- package/dist/dev-server/vite-proxy.d.ts +56 -0
- package/dist/dev-server/vite-proxy.js +212 -0
- package/dist/dev-server/watcher.d.ts +48 -0
- package/dist/dev-server/watcher.js +127 -0
- package/dist/router/codegen-enhanced.d.ts +5 -0
- package/dist/router/codegen-enhanced.js +275 -0
- package/dist/router/codegen.d.ts +17 -0
- package/dist/router/codegen.js +654 -0
- package/dist/router/index.d.ts +16 -0
- package/dist/router/index.js +19 -0
- package/dist/router/scanner.d.ts +86 -0
- package/dist/router/scanner.js +689 -0
- package/dist/router/ssg.d.ts +115 -0
- package/dist/router/ssg.js +202 -0
- package/dist/router/types.d.ts +124 -0
- package/dist/router/types.js +9 -0
- package/dist/router/watch.d.ts +38 -0
- package/dist/router/watch.js +135 -0
- package/dist/runtime/csrf.d.ts +146 -0
- package/dist/runtime/csrf.js +166 -0
- package/dist/runtime/error-boundary.d.ts +129 -0
- package/dist/runtime/error-boundary.js +287 -0
- package/dist/runtime/hooks.d.ts +83 -0
- package/dist/runtime/hooks.js +96 -0
- package/dist/runtime/index.d.ts +229 -0
- package/dist/runtime/index.js +449 -0
- package/dist/runtime/ipc-client.d.ts +144 -0
- package/dist/runtime/ipc-client.js +621 -0
- package/dist/runtime/logger.d.ts +71 -0
- package/dist/runtime/logger.js +164 -0
- package/dist/runtime/middleware.d.ts +66 -0
- package/dist/runtime/middleware.js +114 -0
- package/dist/runtime/process-manager.d.ts +51 -0
- package/dist/runtime/process-manager.js +207 -0
- package/dist/runtime/router-simple.d.ts +98 -0
- package/dist/runtime/router-simple.js +330 -0
- package/dist/runtime/router.d.ts +103 -0
- package/dist/runtime/router.js +435 -0
- package/dist/runtime/rpc-client.d.ts +35 -0
- package/dist/runtime/rpc-client.js +140 -0
- package/dist/runtime/streaming-utils.d.ts +86 -0
- package/dist/runtime/streaming-utils.js +150 -0
- package/dist/runtime/types.d.ts +465 -0
- package/dist/runtime/types.js +60 -0
- package/dist/runtime/websockets-utils.d.ts +50 -0
- package/dist/runtime/websockets-utils.js +92 -0
- package/package.json +30 -20
- package/index.js +0 -29
- package/internal/cli/package.json +0 -46
- package/internal/cli/tsconfig.tsbuildinfo +0 -1
- package/internal/dev-server/node_modules/ora/index.d.ts +0 -332
- package/internal/dev-server/node_modules/ora/index.js +0 -416
- package/internal/dev-server/node_modules/ora/license +0 -9
- package/internal/dev-server/node_modules/ora/node_modules/string-width/index.d.ts +0 -36
- package/internal/dev-server/node_modules/ora/node_modules/string-width/index.js +0 -65
- package/internal/dev-server/node_modules/ora/node_modules/string-width/license +0 -9
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/LICENSE-MIT.txt +0 -20
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/README.md +0 -107
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.d.ts +0 -3
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.js +0 -4
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/index.mjs +0 -4
- package/internal/dev-server/node_modules/ora/node_modules/string-width/node_modules/emoji-regex/package.json +0 -46
- package/internal/dev-server/node_modules/ora/node_modules/string-width/package.json +0 -60
- package/internal/dev-server/node_modules/ora/node_modules/string-width/readme.md +0 -62
- package/internal/dev-server/node_modules/ora/package.json +0 -66
- package/internal/dev-server/node_modules/ora/readme.md +0 -325
- package/internal/dev-server/package.json +0 -41
- package/internal/router/package.json +0 -28
- package/internal/runtime/package.json +0 -41
- package/internal/runtime/src/error-boundary.tsx +0 -476
- package/internal/runtime/src/router-simple.tsx +0 -640
- package/internal/runtime/src/router.tsx +0 -771
- package/internal/runtime/tsconfig.tsbuildinfo +0 -1
- package/src/errors.js +0 -33
- package/src/logger.js +0 -10
- package/src/middleware.js +0 -32
- package/src/router.js +0 -41
- package/src/types.js +0 -39
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CSRF (Cross-Site Request Forgery) Protection Utilities
|
|
3
|
+
*
|
|
4
|
+
* Provides client-side utilities for working with CSRF tokens:
|
|
5
|
+
* - Reading tokens from cookies
|
|
6
|
+
* - Including tokens in fetch requests
|
|
7
|
+
* - Form components with automatic token injection
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* CSRF configuration
|
|
11
|
+
*/
|
|
12
|
+
export interface CsrfConfig {
|
|
13
|
+
/** Cookie name for CSRF token (default: "csrf_token") */
|
|
14
|
+
cookieName?: string;
|
|
15
|
+
/** Header name for CSRF token (default: "X-CSRF-Token") */
|
|
16
|
+
headerName?: string;
|
|
17
|
+
/** Form field name for CSRF token (default: "_csrf") */
|
|
18
|
+
formFieldName?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Get CSRF token from cookie
|
|
22
|
+
*/
|
|
23
|
+
export declare function getCsrfToken(config?: CsrfConfig): string | null;
|
|
24
|
+
/**
|
|
25
|
+
* React hook to get CSRF token
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```tsx
|
|
29
|
+
* function MyComponent() {
|
|
30
|
+
* const csrfToken = useCsrfToken();
|
|
31
|
+
*
|
|
32
|
+
* const handleSubmit = async () => {
|
|
33
|
+
* await fetch('/api/data', {
|
|
34
|
+
* method: 'POST',
|
|
35
|
+
* headers: {
|
|
36
|
+
* 'X-CSRF-Token': csrfToken || '',
|
|
37
|
+
* 'Content-Type': 'application/json',
|
|
38
|
+
* },
|
|
39
|
+
* body: JSON.stringify({ data: 'value' }),
|
|
40
|
+
* });
|
|
41
|
+
* };
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export declare function useCsrfToken(config?: CsrfConfig): string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Create a fetch wrapper that automatically includes CSRF token
|
|
48
|
+
*
|
|
49
|
+
* @example
|
|
50
|
+
* ```tsx
|
|
51
|
+
* const csrfFetch = createCsrfFetch();
|
|
52
|
+
*
|
|
53
|
+
* // Token is automatically included in POST/PUT/DELETE/PATCH requests
|
|
54
|
+
* await csrfFetch('/api/data', {
|
|
55
|
+
* method: 'POST',
|
|
56
|
+
* body: JSON.stringify({ data: 'value' }),
|
|
57
|
+
* });
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function createCsrfFetch(config?: CsrfConfig): typeof fetch;
|
|
61
|
+
/**
|
|
62
|
+
* CSRF token input component for forms
|
|
63
|
+
*
|
|
64
|
+
* @example
|
|
65
|
+
* ```tsx
|
|
66
|
+
* function MyForm() {
|
|
67
|
+
* return (
|
|
68
|
+
* <form method="POST" action="/api/submit">
|
|
69
|
+
* <CsrfTokenInput />
|
|
70
|
+
* <input name="username" />
|
|
71
|
+
* <button type="submit">Submit</button>
|
|
72
|
+
* </form>
|
|
73
|
+
* );
|
|
74
|
+
* }
|
|
75
|
+
* ```
|
|
76
|
+
*/
|
|
77
|
+
export interface CsrfTokenInputProps {
|
|
78
|
+
/** Configuration for CSRF token retrieval */
|
|
79
|
+
config?: CsrfConfig;
|
|
80
|
+
}
|
|
81
|
+
export declare function CsrfTokenInput({ config }: CsrfTokenInputProps): import("react/jsx-runtime").JSX.Element | null;
|
|
82
|
+
/**
|
|
83
|
+
* Enhanced form component with automatic CSRF protection
|
|
84
|
+
*
|
|
85
|
+
* @example
|
|
86
|
+
* ```tsx
|
|
87
|
+
* function MyPage() {
|
|
88
|
+
* const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
|
|
89
|
+
* e.preventDefault();
|
|
90
|
+
* const formData = new FormData(e.currentTarget);
|
|
91
|
+
* await fetch('/api/submit', {
|
|
92
|
+
* method: 'POST',
|
|
93
|
+
* body: formData,
|
|
94
|
+
* });
|
|
95
|
+
* };
|
|
96
|
+
*
|
|
97
|
+
* return (
|
|
98
|
+
* <CsrfForm onSubmit={handleSubmit}>
|
|
99
|
+
* <input name="username" />
|
|
100
|
+
* <button type="submit">Submit</button>
|
|
101
|
+
* </CsrfForm>
|
|
102
|
+
* );
|
|
103
|
+
* }
|
|
104
|
+
* ```
|
|
105
|
+
*/
|
|
106
|
+
export interface CsrfFormProps extends React.FormHTMLAttributes<HTMLFormElement> {
|
|
107
|
+
/** Configuration for CSRF token retrieval */
|
|
108
|
+
config?: CsrfConfig;
|
|
109
|
+
/** Child elements */
|
|
110
|
+
children: React.ReactNode;
|
|
111
|
+
}
|
|
112
|
+
export declare function CsrfForm({ config, children, ...formProps }: CsrfFormProps): import("react/jsx-runtime").JSX.Element;
|
|
113
|
+
/**
|
|
114
|
+
* Utility to manually add CSRF token to FormData
|
|
115
|
+
*
|
|
116
|
+
* @example
|
|
117
|
+
* ```tsx
|
|
118
|
+
* const formData = new FormData();
|
|
119
|
+
* formData.append('username', 'john');
|
|
120
|
+
* addCsrfToFormData(formData);
|
|
121
|
+
*
|
|
122
|
+
* await fetch('/api/submit', {
|
|
123
|
+
* method: 'POST',
|
|
124
|
+
* body: formData,
|
|
125
|
+
* });
|
|
126
|
+
* ```
|
|
127
|
+
*/
|
|
128
|
+
export declare function addCsrfToFormData(formData: FormData, config?: CsrfConfig): void;
|
|
129
|
+
/**
|
|
130
|
+
* Utility to get headers object with CSRF token
|
|
131
|
+
*
|
|
132
|
+
* @example
|
|
133
|
+
* ```tsx
|
|
134
|
+
* const headers = {
|
|
135
|
+
* 'Content-Type': 'application/json',
|
|
136
|
+
* ...getCsrfHeaders(),
|
|
137
|
+
* };
|
|
138
|
+
*
|
|
139
|
+
* await fetch('/api/data', {
|
|
140
|
+
* method: 'POST',
|
|
141
|
+
* headers,
|
|
142
|
+
* body: JSON.stringify({ data: 'value' }),
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare function getCsrfHeaders(config?: CsrfConfig): Record<string, string>;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* CSRF (Cross-Site Request Forgery) Protection Utilities
|
|
4
|
+
*
|
|
5
|
+
* Provides client-side utilities for working with CSRF tokens:
|
|
6
|
+
* - Reading tokens from cookies
|
|
7
|
+
* - Including tokens in fetch requests
|
|
8
|
+
* - Form components with automatic token injection
|
|
9
|
+
*/
|
|
10
|
+
import { useState, useEffect } from 'react';
|
|
11
|
+
const DEFAULT_CONFIG = {
|
|
12
|
+
cookieName: 'csrf_token',
|
|
13
|
+
headerName: 'X-CSRF-Token',
|
|
14
|
+
formFieldName: '_csrf',
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Get CSRF token from cookie
|
|
18
|
+
*/
|
|
19
|
+
export function getCsrfToken(config = {}) {
|
|
20
|
+
const { cookieName } = { ...DEFAULT_CONFIG, ...config };
|
|
21
|
+
if (typeof document === 'undefined') {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const cookies = document.cookie.split(';');
|
|
25
|
+
for (const cookie of cookies) {
|
|
26
|
+
const [name, value] = cookie.trim().split('=');
|
|
27
|
+
if (name === cookieName) {
|
|
28
|
+
return value;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* React hook to get CSRF token
|
|
35
|
+
*
|
|
36
|
+
* @example
|
|
37
|
+
* ```tsx
|
|
38
|
+
* function MyComponent() {
|
|
39
|
+
* const csrfToken = useCsrfToken();
|
|
40
|
+
*
|
|
41
|
+
* const handleSubmit = async () => {
|
|
42
|
+
* await fetch('/api/data', {
|
|
43
|
+
* method: 'POST',
|
|
44
|
+
* headers: {
|
|
45
|
+
* 'X-CSRF-Token': csrfToken || '',
|
|
46
|
+
* 'Content-Type': 'application/json',
|
|
47
|
+
* },
|
|
48
|
+
* body: JSON.stringify({ data: 'value' }),
|
|
49
|
+
* });
|
|
50
|
+
* };
|
|
51
|
+
* }
|
|
52
|
+
* ```
|
|
53
|
+
*/
|
|
54
|
+
export function useCsrfToken(config = {}) {
|
|
55
|
+
const [token, setToken] = useState(() => getCsrfToken(config));
|
|
56
|
+
useEffect(() => {
|
|
57
|
+
// Update token if cookie changes
|
|
58
|
+
const interval = setInterval(() => {
|
|
59
|
+
const newToken = getCsrfToken(config);
|
|
60
|
+
if (newToken !== token) {
|
|
61
|
+
setToken(newToken);
|
|
62
|
+
}
|
|
63
|
+
}, 1000);
|
|
64
|
+
return () => clearInterval(interval);
|
|
65
|
+
}, [config, token]);
|
|
66
|
+
return token;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Create a fetch wrapper that automatically includes CSRF token
|
|
70
|
+
*
|
|
71
|
+
* @example
|
|
72
|
+
* ```tsx
|
|
73
|
+
* const csrfFetch = createCsrfFetch();
|
|
74
|
+
*
|
|
75
|
+
* // Token is automatically included in POST/PUT/DELETE/PATCH requests
|
|
76
|
+
* await csrfFetch('/api/data', {
|
|
77
|
+
* method: 'POST',
|
|
78
|
+
* body: JSON.stringify({ data: 'value' }),
|
|
79
|
+
* });
|
|
80
|
+
* ```
|
|
81
|
+
*/
|
|
82
|
+
export function createCsrfFetch(config = {}) {
|
|
83
|
+
const { headerName } = { ...DEFAULT_CONFIG, ...config };
|
|
84
|
+
return async (input, init) => {
|
|
85
|
+
const token = getCsrfToken(config);
|
|
86
|
+
// Only add token for state-changing methods
|
|
87
|
+
const method = init?.method?.toUpperCase() || 'GET';
|
|
88
|
+
const needsToken = ['POST', 'PUT', 'DELETE', 'PATCH'].includes(method);
|
|
89
|
+
if (needsToken && token) {
|
|
90
|
+
const headers = new Headers(init?.headers);
|
|
91
|
+
if (!headers.has(headerName)) {
|
|
92
|
+
headers.set(headerName, token);
|
|
93
|
+
}
|
|
94
|
+
return fetch(input, {
|
|
95
|
+
...init,
|
|
96
|
+
headers,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
return fetch(input, init);
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
export function CsrfTokenInput({ config = {} }) {
|
|
103
|
+
const token = useCsrfToken(config);
|
|
104
|
+
const { formFieldName } = { ...DEFAULT_CONFIG, ...config };
|
|
105
|
+
if (!token) {
|
|
106
|
+
console.warn('CSRF token not found. Form submission may fail.');
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
return _jsx("input", { type: "hidden", name: formFieldName, value: token });
|
|
110
|
+
}
|
|
111
|
+
export function CsrfForm({ config, children, ...formProps }) {
|
|
112
|
+
return (_jsxs("form", { ...formProps, children: [_jsx(CsrfTokenInput, { config: config }), children] }));
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Utility to manually add CSRF token to FormData
|
|
116
|
+
*
|
|
117
|
+
* @example
|
|
118
|
+
* ```tsx
|
|
119
|
+
* const formData = new FormData();
|
|
120
|
+
* formData.append('username', 'john');
|
|
121
|
+
* addCsrfToFormData(formData);
|
|
122
|
+
*
|
|
123
|
+
* await fetch('/api/submit', {
|
|
124
|
+
* method: 'POST',
|
|
125
|
+
* body: formData,
|
|
126
|
+
* });
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
export function addCsrfToFormData(formData, config = {}) {
|
|
130
|
+
const token = getCsrfToken(config);
|
|
131
|
+
const { formFieldName } = { ...DEFAULT_CONFIG, ...config };
|
|
132
|
+
if (token) {
|
|
133
|
+
formData.append(formFieldName, token);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
console.warn('CSRF token not found. FormData submission may fail.');
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Utility to get headers object with CSRF token
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* ```tsx
|
|
144
|
+
* const headers = {
|
|
145
|
+
* 'Content-Type': 'application/json',
|
|
146
|
+
* ...getCsrfHeaders(),
|
|
147
|
+
* };
|
|
148
|
+
*
|
|
149
|
+
* await fetch('/api/data', {
|
|
150
|
+
* method: 'POST',
|
|
151
|
+
* headers,
|
|
152
|
+
* body: JSON.stringify({ data: 'value' }),
|
|
153
|
+
* });
|
|
154
|
+
* ```
|
|
155
|
+
*/
|
|
156
|
+
export function getCsrfHeaders(config = {}) {
|
|
157
|
+
const token = getCsrfToken(config);
|
|
158
|
+
const { headerName } = { ...DEFAULT_CONFIG, ...config };
|
|
159
|
+
if (!token) {
|
|
160
|
+
console.warn('CSRF token not found. Request may fail.');
|
|
161
|
+
return {};
|
|
162
|
+
}
|
|
163
|
+
return {
|
|
164
|
+
[headerName]: token,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ZapJS Error Boundary
|
|
3
|
+
*
|
|
4
|
+
* TanStack Router style error boundary with explicit errorComponent prop.
|
|
5
|
+
* Provides structured error handling with server error correlation.
|
|
6
|
+
*/
|
|
7
|
+
import React, { Component, type ReactNode, type ErrorInfo } from 'react';
|
|
8
|
+
/**
|
|
9
|
+
* Structured route error with full context
|
|
10
|
+
*
|
|
11
|
+
* Matches the ErrorResponse from Rust server for consistency.
|
|
12
|
+
*/
|
|
13
|
+
export interface ZapRouteError {
|
|
14
|
+
/** Human-readable error message */
|
|
15
|
+
message: string;
|
|
16
|
+
/** Stack trace (development only) */
|
|
17
|
+
stack?: string;
|
|
18
|
+
/** Unique error identifier for log correlation (from server) */
|
|
19
|
+
digest?: string;
|
|
20
|
+
/** Machine-readable error code (e.g., "HANDLER_ERROR", "VALIDATION_ERROR") */
|
|
21
|
+
code?: string;
|
|
22
|
+
/** HTTP status code */
|
|
23
|
+
status?: number;
|
|
24
|
+
/** Additional error-specific details */
|
|
25
|
+
details?: Record<string, unknown>;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Props for error component
|
|
29
|
+
*/
|
|
30
|
+
export interface ErrorComponentProps {
|
|
31
|
+
/** The error that was caught */
|
|
32
|
+
error: ZapRouteError;
|
|
33
|
+
/** Reset function to retry rendering */
|
|
34
|
+
reset: () => void;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Error component type (TanStack style)
|
|
38
|
+
*/
|
|
39
|
+
export type ErrorComponent = React.ComponentType<ErrorComponentProps>;
|
|
40
|
+
interface RouteErrorContextValue {
|
|
41
|
+
error: ZapRouteError;
|
|
42
|
+
reset: () => void;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Context for accessing error state in error components
|
|
46
|
+
*/
|
|
47
|
+
export declare const RouteErrorContext: React.Context<RouteErrorContextValue | null>;
|
|
48
|
+
interface ErrorBoundaryProps {
|
|
49
|
+
/** The content to render when no error */
|
|
50
|
+
children: ReactNode;
|
|
51
|
+
/** Custom error component (TanStack style) */
|
|
52
|
+
errorComponent?: ErrorComponent;
|
|
53
|
+
/** Fallback when no errorComponent provided */
|
|
54
|
+
fallback?: ReactNode;
|
|
55
|
+
/** Callback when an error is caught */
|
|
56
|
+
onError?: (error: ZapRouteError, errorInfo: ErrorInfo) => void;
|
|
57
|
+
/** Reset keys - when these change, the boundary resets */
|
|
58
|
+
resetKeys?: unknown[];
|
|
59
|
+
}
|
|
60
|
+
interface ErrorBoundaryState {
|
|
61
|
+
hasError: boolean;
|
|
62
|
+
error: ZapRouteError | null;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Error Boundary with TanStack Router style errorComponent prop
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```tsx
|
|
69
|
+
* // Route file: routes/users.$id.tsx
|
|
70
|
+
* export default function UserPage() {
|
|
71
|
+
* // ... component
|
|
72
|
+
* }
|
|
73
|
+
*
|
|
74
|
+
* export function errorComponent({ error, reset }: ErrorComponentProps) {
|
|
75
|
+
* return (
|
|
76
|
+
* <div>
|
|
77
|
+
* <h1>Failed to load user</h1>
|
|
78
|
+
* <p>{error.message}</p>
|
|
79
|
+
* {error.digest && <small>Error ID: {error.digest}</small>}
|
|
80
|
+
* <button onClick={reset}>Try Again</button>
|
|
81
|
+
* </div>
|
|
82
|
+
* );
|
|
83
|
+
* }
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
87
|
+
constructor(props: ErrorBoundaryProps);
|
|
88
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
89
|
+
componentDidCatch(error: Error, errorInfo: ErrorInfo): void;
|
|
90
|
+
componentDidUpdate(prevProps: ErrorBoundaryProps): void;
|
|
91
|
+
/**
|
|
92
|
+
* Reset the error boundary state
|
|
93
|
+
*/
|
|
94
|
+
reset: () => void;
|
|
95
|
+
render(): ReactNode;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Default error fallback UI
|
|
99
|
+
*
|
|
100
|
+
* Shows:
|
|
101
|
+
* - Error message
|
|
102
|
+
* - Error code (if available)
|
|
103
|
+
* - Error digest (for server errors)
|
|
104
|
+
* - Stack trace (development only)
|
|
105
|
+
* - "Try Again" button
|
|
106
|
+
*/
|
|
107
|
+
export declare function DefaultErrorComponent({ error, reset }: ErrorComponentProps): JSX.Element;
|
|
108
|
+
/**
|
|
109
|
+
* Create a ZapRouteError from server error response
|
|
110
|
+
*/
|
|
111
|
+
export declare function createRouteError(options: {
|
|
112
|
+
message: string;
|
|
113
|
+
code?: string;
|
|
114
|
+
status?: number;
|
|
115
|
+
digest?: string;
|
|
116
|
+
details?: Record<string, unknown>;
|
|
117
|
+
}): ZapRouteError;
|
|
118
|
+
/**
|
|
119
|
+
* Wrap an Error with ZapRouteError metadata
|
|
120
|
+
*/
|
|
121
|
+
export declare class ZapError extends Error {
|
|
122
|
+
code?: string;
|
|
123
|
+
status?: number;
|
|
124
|
+
digest?: string;
|
|
125
|
+
details?: Record<string, unknown>;
|
|
126
|
+
constructor(message: string, options?: Omit<ZapRouteError, 'message' | 'stack'>);
|
|
127
|
+
toRouteError(): ZapRouteError;
|
|
128
|
+
}
|
|
129
|
+
export {};
|