forked from jsnbuchanan/crowd-funder-for-time-pwa
- Add comprehensive route validation with zod schema - Create type-safe DeepLinkRoute enum for all valid routes - Add structured error handling for invalid routes - Redirect to error page with detailed feedback - Add better timeout handling in deeplink tests The changes improve robustness by: 1. Validating route paths before navigation 2. Providing detailed error messages for invalid links 3. Redirecting users to dedicated error pages 4. Adding parameter validation with specific feedback 5. Improving type safety across deeplink handling
104 lines
2.7 KiB
TypeScript
104 lines
2.7 KiB
TypeScript
/**
|
|
* @file Deep Link Type Definitions and Validation Schemas
|
|
* @author Matthew Raymer
|
|
*
|
|
* This file defines the type system and validation schemas for deep linking in the TimeSafari app.
|
|
* It uses Zod for runtime validation while providing TypeScript types for compile-time checking.
|
|
*
|
|
* Type Strategy:
|
|
* 1. Define base URL schema to validate the fundamental deep link structure
|
|
* 2. Define route-specific parameter schemas with exact validation rules
|
|
* 3. Generate TypeScript types from Zod schemas for type safety
|
|
* 4. Export both schemas and types for use in deep link handling
|
|
*
|
|
* Usage:
|
|
* - Import schemas for runtime validation in deep link handlers
|
|
* - Import types for type-safe parameter handling in components
|
|
* - Use DeepLinkParams type for type-safe access to route parameters
|
|
*
|
|
* @example
|
|
* // Runtime validation
|
|
* const params = deepLinkSchemas.claim.parse({ id: "123", view: "details" });
|
|
*
|
|
* // Type-safe parameter access
|
|
* function handleClaimParams(params: DeepLinkParams["claim"]) {
|
|
* // TypeScript knows params.id exists and params.view is optional
|
|
* }
|
|
*/
|
|
import { z } from "zod";
|
|
|
|
// Add a union type of all valid route paths
|
|
export const VALID_DEEP_LINK_ROUTES = [
|
|
"user-profile",
|
|
"project-details",
|
|
"onboard-meeting-setup",
|
|
"invite-one-accept",
|
|
"contact-import",
|
|
"confirm-gift",
|
|
"claim",
|
|
"claim-cert",
|
|
"claim-add-raw",
|
|
"contact-edit",
|
|
"contacts",
|
|
"did",
|
|
] as const;
|
|
|
|
// Create a type from the array
|
|
export type DeepLinkRoute = (typeof VALID_DEEP_LINK_ROUTES)[number];
|
|
|
|
// Update your schema definitions to use this type
|
|
export const baseUrlSchema = z.object({
|
|
scheme: z.literal("timesafari"),
|
|
path: z.string(),
|
|
queryParams: z.record(z.string()).optional(),
|
|
});
|
|
|
|
// Use the type to ensure route validation
|
|
export const routeSchema = z.enum(VALID_DEEP_LINK_ROUTES);
|
|
|
|
// Parameter validation schemas for each route type
|
|
export const deepLinkSchemas = {
|
|
"user-profile": z.object({
|
|
id: z.string(),
|
|
}),
|
|
"project-details": z.object({
|
|
id: z.string(),
|
|
}),
|
|
"onboard-meeting-setup": z.object({
|
|
id: z.string(),
|
|
}),
|
|
"invite-one-accept": z.object({
|
|
id: z.string(),
|
|
}),
|
|
"contact-import": z.object({
|
|
jwt: z.string(),
|
|
}),
|
|
"confirm-gift": z.object({
|
|
id: z.string(),
|
|
}),
|
|
claim: z.object({
|
|
id: z.string(),
|
|
}),
|
|
"claim-cert": z.object({
|
|
id: z.string(),
|
|
}),
|
|
"claim-add-raw": z.object({
|
|
id: z.string(),
|
|
claim: z.string().optional(),
|
|
claimJwtId: z.string().optional(),
|
|
}),
|
|
"contact-edit": z.object({
|
|
did: z.string(),
|
|
}),
|
|
contacts: z.object({
|
|
contacts: z.string(), // JSON string of contacts array
|
|
}),
|
|
did: z.object({
|
|
id: z.string(),
|
|
}),
|
|
};
|
|
|
|
export type DeepLinkParams = {
|
|
[K in keyof typeof deepLinkSchemas]: z.infer<(typeof deepLinkSchemas)[K]>;
|
|
};
|