@zap-js/client 0.0.2 → 0.0.4
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 +71 -0
- package/dist/dev-server/route-scanner.js +114 -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 +658 -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
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@internal/zapjs/router",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"description": "File-based routing for ZapJS (TanStack style)",
|
|
6
|
-
"main": "dist/index.js",
|
|
7
|
-
"types": "dist/index.d.ts",
|
|
8
|
-
"type": "module",
|
|
9
|
-
"scripts": {
|
|
10
|
-
"build": "tsc",
|
|
11
|
-
"dev": "tsc --watch"
|
|
12
|
-
},
|
|
13
|
-
"keywords": [
|
|
14
|
-
"zap",
|
|
15
|
-
"router",
|
|
16
|
-
"file-based-routing",
|
|
17
|
-
"tanstack"
|
|
18
|
-
],
|
|
19
|
-
"author": "saint0x",
|
|
20
|
-
"license": "MIT",
|
|
21
|
-
"dependencies": {
|
|
22
|
-
"chokidar": "^3.5.3"
|
|
23
|
-
},
|
|
24
|
-
"devDependencies": {
|
|
25
|
-
"@types/node": "^20.0.0",
|
|
26
|
-
"typescript": "^5.0.0"
|
|
27
|
-
}
|
|
28
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@internal/zapjs/runtime",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"private": true,
|
|
5
|
-
"description": "ZapRS runtime - TypeScript wrapper for Rust backend",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"main": "dist/index.js",
|
|
8
|
-
"types": "dist/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"import": "./dist/index.js",
|
|
12
|
-
"require": "./dist/index.js",
|
|
13
|
-
"types": "./dist/index.d.ts"
|
|
14
|
-
}
|
|
15
|
-
},
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "tsc",
|
|
18
|
-
"dev": "bun run src/index.ts"
|
|
19
|
-
},
|
|
20
|
-
"files": [
|
|
21
|
-
"dist",
|
|
22
|
-
"README.md"
|
|
23
|
-
],
|
|
24
|
-
"keywords": [
|
|
25
|
-
"zap",
|
|
26
|
-
"runtime",
|
|
27
|
-
"rust",
|
|
28
|
-
"typescript"
|
|
29
|
-
],
|
|
30
|
-
"author": "saint0x",
|
|
31
|
-
"license": "MIT",
|
|
32
|
-
"engines": {
|
|
33
|
-
"node": ">=16.0.0"
|
|
34
|
-
},
|
|
35
|
-
"peerDependencies": {
|
|
36
|
-
"node": ">=16.0.0"
|
|
37
|
-
},
|
|
38
|
-
"dependencies": {
|
|
39
|
-
"@msgpack/msgpack": "^3.0.0"
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,476 +0,0 @@
|
|
|
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
|
-
|
|
8
|
-
import React, { Component, createContext, useContext, type ReactNode, type ErrorInfo } from 'react';
|
|
9
|
-
|
|
10
|
-
// ============================================================================
|
|
11
|
-
// Error Types
|
|
12
|
-
// ============================================================================
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Structured route error with full context
|
|
16
|
-
*
|
|
17
|
-
* Matches the ErrorResponse from Rust server for consistency.
|
|
18
|
-
*/
|
|
19
|
-
export interface ZapRouteError {
|
|
20
|
-
/** Human-readable error message */
|
|
21
|
-
message: string;
|
|
22
|
-
/** Stack trace (development only) */
|
|
23
|
-
stack?: string;
|
|
24
|
-
/** Unique error identifier for log correlation (from server) */
|
|
25
|
-
digest?: string;
|
|
26
|
-
/** Machine-readable error code (e.g., "HANDLER_ERROR", "VALIDATION_ERROR") */
|
|
27
|
-
code?: string;
|
|
28
|
-
/** HTTP status code */
|
|
29
|
-
status?: number;
|
|
30
|
-
/** Additional error-specific details */
|
|
31
|
-
details?: Record<string, unknown>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Props for error component
|
|
36
|
-
*/
|
|
37
|
-
export interface ErrorComponentProps {
|
|
38
|
-
/** The error that was caught */
|
|
39
|
-
error: ZapRouteError;
|
|
40
|
-
/** Reset function to retry rendering */
|
|
41
|
-
reset: () => void;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Error component type (TanStack style)
|
|
46
|
-
*/
|
|
47
|
-
export type ErrorComponent = React.ComponentType<ErrorComponentProps>;
|
|
48
|
-
|
|
49
|
-
// ============================================================================
|
|
50
|
-
// Context
|
|
51
|
-
// ============================================================================
|
|
52
|
-
|
|
53
|
-
interface RouteErrorContextValue {
|
|
54
|
-
error: ZapRouteError;
|
|
55
|
-
reset: () => void;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Context for accessing error state in error components
|
|
60
|
-
*/
|
|
61
|
-
export const RouteErrorContext = createContext<RouteErrorContextValue | null>(null);
|
|
62
|
-
|
|
63
|
-
// ============================================================================
|
|
64
|
-
// Error Boundary Component
|
|
65
|
-
// ============================================================================
|
|
66
|
-
|
|
67
|
-
interface ErrorBoundaryProps {
|
|
68
|
-
/** The content to render when no error */
|
|
69
|
-
children: ReactNode;
|
|
70
|
-
/** Custom error component (TanStack style) */
|
|
71
|
-
errorComponent?: ErrorComponent;
|
|
72
|
-
/** Fallback when no errorComponent provided */
|
|
73
|
-
fallback?: ReactNode;
|
|
74
|
-
/** Callback when an error is caught */
|
|
75
|
-
onError?: (error: ZapRouteError, errorInfo: ErrorInfo) => void;
|
|
76
|
-
/** Reset keys - when these change, the boundary resets */
|
|
77
|
-
resetKeys?: unknown[];
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
interface ErrorBoundaryState {
|
|
81
|
-
hasError: boolean;
|
|
82
|
-
error: ZapRouteError | null;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Error Boundary with TanStack Router style errorComponent prop
|
|
87
|
-
*
|
|
88
|
-
* @example
|
|
89
|
-
* ```tsx
|
|
90
|
-
* // Route file: routes/users.$id.tsx
|
|
91
|
-
* export default function UserPage() {
|
|
92
|
-
* // ... component
|
|
93
|
-
* }
|
|
94
|
-
*
|
|
95
|
-
* export function errorComponent({ error, reset }: ErrorComponentProps) {
|
|
96
|
-
* return (
|
|
97
|
-
* <div>
|
|
98
|
-
* <h1>Failed to load user</h1>
|
|
99
|
-
* <p>{error.message}</p>
|
|
100
|
-
* {error.digest && <small>Error ID: {error.digest}</small>}
|
|
101
|
-
* <button onClick={reset}>Try Again</button>
|
|
102
|
-
* </div>
|
|
103
|
-
* );
|
|
104
|
-
* }
|
|
105
|
-
* ```
|
|
106
|
-
*/
|
|
107
|
-
export class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
108
|
-
constructor(props: ErrorBoundaryProps) {
|
|
109
|
-
super(props);
|
|
110
|
-
this.state = { hasError: false, error: null };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
static getDerivedStateFromError(error: Error): ErrorBoundaryState {
|
|
114
|
-
// Convert Error to ZapRouteError
|
|
115
|
-
const zapError = normalizeError(error);
|
|
116
|
-
return { hasError: true, error: zapError };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
componentDidCatch(error: Error, errorInfo: ErrorInfo): void {
|
|
120
|
-
const zapError = normalizeError(error);
|
|
121
|
-
|
|
122
|
-
// Call onError callback if provided
|
|
123
|
-
if (this.props.onError) {
|
|
124
|
-
this.props.onError(zapError, errorInfo);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
// Log error in development
|
|
128
|
-
if (process.env.NODE_ENV !== 'production') {
|
|
129
|
-
console.error('[ErrorBoundary] Caught error:', error);
|
|
130
|
-
console.error('[ErrorBoundary] Component stack:', errorInfo.componentStack);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
componentDidUpdate(prevProps: ErrorBoundaryProps): void {
|
|
135
|
-
// Reset error state when resetKeys change
|
|
136
|
-
if (this.state.hasError && this.props.resetKeys) {
|
|
137
|
-
const prevKeys = prevProps.resetKeys || [];
|
|
138
|
-
const currentKeys = this.props.resetKeys;
|
|
139
|
-
|
|
140
|
-
const hasChanged = currentKeys.some(
|
|
141
|
-
(key, index) => key !== prevKeys[index]
|
|
142
|
-
);
|
|
143
|
-
|
|
144
|
-
if (hasChanged) {
|
|
145
|
-
this.reset();
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* Reset the error boundary state
|
|
152
|
-
*/
|
|
153
|
-
reset = (): void => {
|
|
154
|
-
this.setState({ hasError: false, error: null });
|
|
155
|
-
};
|
|
156
|
-
|
|
157
|
-
render(): ReactNode {
|
|
158
|
-
if (this.state.hasError && this.state.error) {
|
|
159
|
-
const { errorComponent: CustomErrorComponent, fallback } = this.props;
|
|
160
|
-
const contextValue: RouteErrorContextValue = {
|
|
161
|
-
error: this.state.error,
|
|
162
|
-
reset: this.reset,
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// Use custom error component if provided (TanStack style)
|
|
166
|
-
if (CustomErrorComponent) {
|
|
167
|
-
return (
|
|
168
|
-
<RouteErrorContext.Provider value={contextValue}>
|
|
169
|
-
<CustomErrorComponent error={this.state.error} reset={this.reset} />
|
|
170
|
-
</RouteErrorContext.Provider>
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
// Use fallback if provided
|
|
175
|
-
if (fallback) {
|
|
176
|
-
return (
|
|
177
|
-
<RouteErrorContext.Provider value={contextValue}>
|
|
178
|
-
{fallback}
|
|
179
|
-
</RouteErrorContext.Provider>
|
|
180
|
-
);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
// Use default error component
|
|
184
|
-
return (
|
|
185
|
-
<RouteErrorContext.Provider value={contextValue}>
|
|
186
|
-
<DefaultErrorComponent error={this.state.error} reset={this.reset} />
|
|
187
|
-
</RouteErrorContext.Provider>
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
return this.props.children;
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
// ============================================================================
|
|
196
|
-
// Default Error Component
|
|
197
|
-
// ============================================================================
|
|
198
|
-
|
|
199
|
-
/**
|
|
200
|
-
* Default error fallback UI
|
|
201
|
-
*
|
|
202
|
-
* Shows:
|
|
203
|
-
* - Error message
|
|
204
|
-
* - Error code (if available)
|
|
205
|
-
* - Error digest (for server errors)
|
|
206
|
-
* - Stack trace (development only)
|
|
207
|
-
* - "Try Again" button
|
|
208
|
-
*/
|
|
209
|
-
export function DefaultErrorComponent({ error, reset }: ErrorComponentProps): JSX.Element {
|
|
210
|
-
const isDev = process.env.NODE_ENV !== 'production';
|
|
211
|
-
|
|
212
|
-
return (
|
|
213
|
-
<div style={styles.container}>
|
|
214
|
-
<div style={styles.content}>
|
|
215
|
-
{/* Error icon */}
|
|
216
|
-
<div style={styles.icon}>
|
|
217
|
-
<svg
|
|
218
|
-
width="48"
|
|
219
|
-
height="48"
|
|
220
|
-
viewBox="0 0 24 24"
|
|
221
|
-
fill="none"
|
|
222
|
-
stroke="currentColor"
|
|
223
|
-
strokeWidth="2"
|
|
224
|
-
strokeLinecap="round"
|
|
225
|
-
strokeLinejoin="round"
|
|
226
|
-
>
|
|
227
|
-
<circle cx="12" cy="12" r="10" />
|
|
228
|
-
<line x1="12" y1="8" x2="12" y2="12" />
|
|
229
|
-
<line x1="12" y1="16" x2="12.01" y2="16" />
|
|
230
|
-
</svg>
|
|
231
|
-
</div>
|
|
232
|
-
|
|
233
|
-
{/* Title */}
|
|
234
|
-
<h1 style={styles.title}>Something went wrong</h1>
|
|
235
|
-
|
|
236
|
-
{/* Error message */}
|
|
237
|
-
<p style={styles.message}>{error.message}</p>
|
|
238
|
-
|
|
239
|
-
{/* Error metadata */}
|
|
240
|
-
<div style={styles.metadata}>
|
|
241
|
-
{error.code && (
|
|
242
|
-
<span style={styles.badge}>
|
|
243
|
-
{error.code}
|
|
244
|
-
</span>
|
|
245
|
-
)}
|
|
246
|
-
{error.status && (
|
|
247
|
-
<span style={styles.badge}>
|
|
248
|
-
{error.status}
|
|
249
|
-
</span>
|
|
250
|
-
)}
|
|
251
|
-
</div>
|
|
252
|
-
|
|
253
|
-
{/* Error digest for correlation */}
|
|
254
|
-
{error.digest && (
|
|
255
|
-
<p style={styles.digest}>
|
|
256
|
-
Error ID: <code style={styles.code}>{error.digest}</code>
|
|
257
|
-
</p>
|
|
258
|
-
)}
|
|
259
|
-
|
|
260
|
-
{/* Stack trace in development */}
|
|
261
|
-
{isDev && error.stack && (
|
|
262
|
-
<details style={styles.details}>
|
|
263
|
-
<summary style={styles.summary}>Stack Trace</summary>
|
|
264
|
-
<pre style={styles.stackTrace}>{error.stack}</pre>
|
|
265
|
-
</details>
|
|
266
|
-
)}
|
|
267
|
-
|
|
268
|
-
{/* Reset button */}
|
|
269
|
-
<button onClick={reset} style={styles.button}>
|
|
270
|
-
Try Again
|
|
271
|
-
</button>
|
|
272
|
-
</div>
|
|
273
|
-
</div>
|
|
274
|
-
);
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
// ============================================================================
|
|
278
|
-
// Styles
|
|
279
|
-
// ============================================================================
|
|
280
|
-
|
|
281
|
-
const styles: Record<string, React.CSSProperties> = {
|
|
282
|
-
container: {
|
|
283
|
-
display: 'flex',
|
|
284
|
-
alignItems: 'center',
|
|
285
|
-
justifyContent: 'center',
|
|
286
|
-
minHeight: '100vh',
|
|
287
|
-
padding: '20px',
|
|
288
|
-
fontFamily: 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
289
|
-
backgroundColor: '#fafafa',
|
|
290
|
-
color: '#1a1a1a',
|
|
291
|
-
},
|
|
292
|
-
content: {
|
|
293
|
-
maxWidth: '500px',
|
|
294
|
-
width: '100%',
|
|
295
|
-
textAlign: 'center' as const,
|
|
296
|
-
padding: '40px',
|
|
297
|
-
backgroundColor: 'white',
|
|
298
|
-
borderRadius: '12px',
|
|
299
|
-
boxShadow: '0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06)',
|
|
300
|
-
},
|
|
301
|
-
icon: {
|
|
302
|
-
marginBottom: '24px',
|
|
303
|
-
color: '#ef4444',
|
|
304
|
-
},
|
|
305
|
-
title: {
|
|
306
|
-
margin: '0 0 12px 0',
|
|
307
|
-
fontSize: '24px',
|
|
308
|
-
fontWeight: 600,
|
|
309
|
-
},
|
|
310
|
-
message: {
|
|
311
|
-
margin: '0 0 16px 0',
|
|
312
|
-
fontSize: '16px',
|
|
313
|
-
color: '#666',
|
|
314
|
-
lineHeight: 1.5,
|
|
315
|
-
},
|
|
316
|
-
metadata: {
|
|
317
|
-
display: 'flex',
|
|
318
|
-
gap: '8px',
|
|
319
|
-
justifyContent: 'center',
|
|
320
|
-
marginBottom: '16px',
|
|
321
|
-
},
|
|
322
|
-
badge: {
|
|
323
|
-
display: 'inline-block',
|
|
324
|
-
padding: '4px 8px',
|
|
325
|
-
fontSize: '12px',
|
|
326
|
-
fontWeight: 500,
|
|
327
|
-
backgroundColor: '#f3f4f6',
|
|
328
|
-
borderRadius: '4px',
|
|
329
|
-
color: '#4b5563',
|
|
330
|
-
},
|
|
331
|
-
digest: {
|
|
332
|
-
margin: '0 0 20px 0',
|
|
333
|
-
fontSize: '13px',
|
|
334
|
-
color: '#888',
|
|
335
|
-
},
|
|
336
|
-
code: {
|
|
337
|
-
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
|
338
|
-
backgroundColor: '#f3f4f6',
|
|
339
|
-
padding: '2px 6px',
|
|
340
|
-
borderRadius: '4px',
|
|
341
|
-
fontSize: '12px',
|
|
342
|
-
},
|
|
343
|
-
details: {
|
|
344
|
-
textAlign: 'left' as const,
|
|
345
|
-
marginBottom: '20px',
|
|
346
|
-
},
|
|
347
|
-
summary: {
|
|
348
|
-
cursor: 'pointer',
|
|
349
|
-
fontSize: '14px',
|
|
350
|
-
color: '#666',
|
|
351
|
-
marginBottom: '8px',
|
|
352
|
-
},
|
|
353
|
-
stackTrace: {
|
|
354
|
-
fontSize: '12px',
|
|
355
|
-
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace',
|
|
356
|
-
backgroundColor: '#1a1a1a',
|
|
357
|
-
color: '#f5f5f5',
|
|
358
|
-
padding: '16px',
|
|
359
|
-
borderRadius: '8px',
|
|
360
|
-
overflow: 'auto',
|
|
361
|
-
maxHeight: '200px',
|
|
362
|
-
margin: 0,
|
|
363
|
-
whiteSpace: 'pre-wrap',
|
|
364
|
-
wordBreak: 'break-word',
|
|
365
|
-
},
|
|
366
|
-
button: {
|
|
367
|
-
padding: '12px 24px',
|
|
368
|
-
fontSize: '14px',
|
|
369
|
-
fontWeight: 500,
|
|
370
|
-
color: 'white',
|
|
371
|
-
backgroundColor: '#3b82f6',
|
|
372
|
-
border: 'none',
|
|
373
|
-
borderRadius: '8px',
|
|
374
|
-
cursor: 'pointer',
|
|
375
|
-
transition: 'background-color 0.2s',
|
|
376
|
-
},
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
// ============================================================================
|
|
380
|
-
// Helper Functions
|
|
381
|
-
// ============================================================================
|
|
382
|
-
|
|
383
|
-
/**
|
|
384
|
-
* Normalize any error to ZapRouteError format
|
|
385
|
-
*/
|
|
386
|
-
function normalizeError(error: unknown): ZapRouteError {
|
|
387
|
-
// Already a ZapRouteError
|
|
388
|
-
if (isZapRouteError(error)) {
|
|
389
|
-
return error;
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
// Standard Error
|
|
393
|
-
if (error instanceof Error) {
|
|
394
|
-
return {
|
|
395
|
-
message: error.message,
|
|
396
|
-
stack: error.stack,
|
|
397
|
-
// Check for extended properties from server errors
|
|
398
|
-
code: (error as { code?: string }).code,
|
|
399
|
-
status: (error as { status?: number }).status,
|
|
400
|
-
digest: (error as { digest?: string }).digest,
|
|
401
|
-
details: (error as { details?: Record<string, unknown> }).details,
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
// String error
|
|
406
|
-
if (typeof error === 'string') {
|
|
407
|
-
return { message: error };
|
|
408
|
-
}
|
|
409
|
-
|
|
410
|
-
// Unknown error type
|
|
411
|
-
return { message: 'An unknown error occurred' };
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
/**
|
|
415
|
-
* Type guard for ZapRouteError
|
|
416
|
-
*/
|
|
417
|
-
function isZapRouteError(error: unknown): error is ZapRouteError {
|
|
418
|
-
return (
|
|
419
|
-
typeof error === 'object' &&
|
|
420
|
-
error !== null &&
|
|
421
|
-
'message' in error &&
|
|
422
|
-
typeof (error as { message: unknown }).message === 'string'
|
|
423
|
-
);
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
/**
|
|
427
|
-
* Create a ZapRouteError from server error response
|
|
428
|
-
*/
|
|
429
|
-
export function createRouteError(options: {
|
|
430
|
-
message: string;
|
|
431
|
-
code?: string;
|
|
432
|
-
status?: number;
|
|
433
|
-
digest?: string;
|
|
434
|
-
details?: Record<string, unknown>;
|
|
435
|
-
}): ZapRouteError {
|
|
436
|
-
return {
|
|
437
|
-
message: options.message,
|
|
438
|
-
code: options.code,
|
|
439
|
-
status: options.status,
|
|
440
|
-
digest: options.digest,
|
|
441
|
-
details: options.details,
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Wrap an Error with ZapRouteError metadata
|
|
447
|
-
*/
|
|
448
|
-
export class ZapError extends Error {
|
|
449
|
-
code?: string;
|
|
450
|
-
status?: number;
|
|
451
|
-
digest?: string;
|
|
452
|
-
details?: Record<string, unknown>;
|
|
453
|
-
|
|
454
|
-
constructor(message: string, options?: Omit<ZapRouteError, 'message' | 'stack'>) {
|
|
455
|
-
super(message);
|
|
456
|
-
this.name = 'ZapError';
|
|
457
|
-
this.code = options?.code;
|
|
458
|
-
this.status = options?.status;
|
|
459
|
-
this.digest = options?.digest;
|
|
460
|
-
this.details = options?.details;
|
|
461
|
-
|
|
462
|
-
// Maintain proper prototype chain
|
|
463
|
-
Object.setPrototypeOf(this, ZapError.prototype);
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
toRouteError(): ZapRouteError {
|
|
467
|
-
return {
|
|
468
|
-
message: this.message,
|
|
469
|
-
stack: this.stack,
|
|
470
|
-
code: this.code,
|
|
471
|
-
status: this.status,
|
|
472
|
-
digest: this.digest,
|
|
473
|
-
details: this.details,
|
|
474
|
-
};
|
|
475
|
-
}
|
|
476
|
-
}
|