forked from trent_larson/crowd-funder-for-time-pwa
refactor: consolidate type system and improve documentation
- Move type definitions from src/types/ to src/interfaces/ for better organization - Enhance deep linking type system documentation with detailed examples - Update package dependencies to latest versions - Improve code organization in README.md - Fix formatting in WebPlatformService.ts This change consolidates all type definitions into the interfaces folder, improves type safety documentation, and updates dependencies for better maintainability. The deep linking system now has clearer documentation about its type system and validation approach. Breaking: Removes src/types/ directory in favor of src/interfaces/
This commit is contained in:
@@ -1,11 +1,106 @@
|
||||
/**
|
||||
* @file Deep Link Interface Definitions
|
||||
* @file Deep Link Type Definitions and Validation Schemas
|
||||
* @author Matthew Raymer
|
||||
*
|
||||
* Defines the core interfaces for the deep linking system.
|
||||
* These interfaces are used across the deep linking implementation
|
||||
* to ensure type safety and consistent error handling.
|
||||
* 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({
|
||||
did: z.string(),
|
||||
}),
|
||||
};
|
||||
|
||||
export type DeepLinkParams = {
|
||||
[K in keyof typeof deepLinkSchemas]: z.infer<(typeof deepLinkSchemas)[K]>;
|
||||
};
|
||||
|
||||
export interface DeepLinkError extends Error {
|
||||
code: string;
|
||||
|
||||
21
src/interfaces/give.ts
Normal file
21
src/interfaces/give.ts
Normal file
@@ -0,0 +1,21 @@
|
||||
import { GiveSummaryRecord } from "./records";
|
||||
|
||||
// Common interface for contact information
|
||||
export interface ContactInfo {
|
||||
known: boolean;
|
||||
displayName: string;
|
||||
profileImageUrl?: string;
|
||||
}
|
||||
|
||||
// Define the contact information fields
|
||||
interface GiveContactInfo {
|
||||
giver: ContactInfo;
|
||||
issuer: ContactInfo;
|
||||
receiver: ContactInfo;
|
||||
providerPlanName?: string;
|
||||
recipientProjectName?: string;
|
||||
image?: string;
|
||||
}
|
||||
|
||||
// Combine GiveSummaryRecord with contact information using intersection type
|
||||
export type GiveRecordWithContactInfo = GiveSummaryRecord & GiveContactInfo;
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* Architecture:
|
||||
* 1. DeepLinkHandler class encapsulates all deep link processing logic
|
||||
* 2. Uses Zod schemas from types/deepLinks for parameter validation
|
||||
* 2. Uses Zod schemas from interfaces/deepLinks for parameter validation
|
||||
* 3. Provides consistent error handling and logging
|
||||
* 4. Maps validated parameters to Vue router calls
|
||||
*
|
||||
@@ -51,7 +51,7 @@ import {
|
||||
baseUrlSchema,
|
||||
routeSchema,
|
||||
DeepLinkRoute,
|
||||
} from "../types/deepLinks";
|
||||
} from "../interfaces/deepLinks";
|
||||
import { logConsoleAndDb } from "../db";
|
||||
import type { DeepLinkError } from "../interfaces/deepLinks";
|
||||
|
||||
|
||||
@@ -132,9 +132,10 @@ export class WebPlatformService implements PlatformService {
|
||||
};
|
||||
|
||||
// Move async operations inside Promise body
|
||||
navigator.mediaDevices.getUserMedia({
|
||||
video: { facingMode: "user" },
|
||||
})
|
||||
navigator.mediaDevices
|
||||
.getUserMedia({
|
||||
video: { facingMode: "user" },
|
||||
})
|
||||
.then((mediaStream) => {
|
||||
stream = mediaStream;
|
||||
// Create overlay for video and button
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/**
|
||||
* @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({
|
||||
did: z.string(),
|
||||
}),
|
||||
};
|
||||
|
||||
export type DeepLinkParams = {
|
||||
[K in keyof typeof deepLinkSchemas]: z.infer<(typeof deepLinkSchemas)[K]>;
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
import { GiveSummaryRecord, GiveVerifiableCredential } from "../interfaces";
|
||||
|
||||
export interface GiveRecordWithContactInfo extends GiveSummaryRecord {
|
||||
jwtId: string;
|
||||
fullClaim: GiveVerifiableCredential;
|
||||
giver: {
|
||||
known: boolean;
|
||||
displayName: string;
|
||||
profileImageUrl?: string;
|
||||
};
|
||||
issuer: {
|
||||
known: boolean;
|
||||
displayName: string;
|
||||
profileImageUrl?: string;
|
||||
};
|
||||
receiver: {
|
||||
known: boolean;
|
||||
displayName: string;
|
||||
profileImageUrl?: string;
|
||||
};
|
||||
providerPlanName?: string;
|
||||
recipientProjectName?: string;
|
||||
description: string;
|
||||
image?: string;
|
||||
}
|
||||
@@ -41,7 +41,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted } from "vue";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { VALID_DEEP_LINK_ROUTES } from "../types/deepLinks";
|
||||
import { VALID_DEEP_LINK_ROUTES } from "../interfaces/deepLinks";
|
||||
import { logConsoleAndDb } from "../db";
|
||||
import { logger } from "../utils/logger";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user