Consolidate deep-link paths to be derived from the same source so they don't get out of sync any more.

This commit is contained in:
2025-07-03 17:01:08 -06:00
parent 1b283a0045
commit 861408c7bc
3 changed files with 54 additions and 57 deletions

View File

@@ -44,6 +44,8 @@
*/
import { Router } from "vue-router";
import { z } from "zod";
import {
deepLinkSchemas,
baseUrlSchema,
@@ -53,6 +55,31 @@ import {
import { logConsoleAndDb } from "../db/databaseUtil";
import type { DeepLinkError } from "../interfaces/deepLinks";
// Helper function to extract the first key from a Zod object schema
function getFirstKeyFromZodObject(schema: z.ZodObject<any>): string | undefined {
const shape = schema.shape;
const keys = Object.keys(shape);
return keys.length > 0 ? keys[0] : undefined;
}
/**
* Maps deep link routes to their corresponding Vue router names and optional parameter keys.
*
* It's an object where keys are the deep link routes and values are objects with 'name' and 'paramKey'.
*
* The paramKey is used to extract the parameter from the route path,
* because "router.replace" expects the right parameter name for the route.
*/
export const ROUTE_MAP: Record<string, { name: string; paramKey?: string }> =
Object.entries(deepLinkSchemas).reduce((acc, [routeName, schema]) => {
const paramKey = getFirstKeyFromZodObject(schema as z.ZodObject<any>);
acc[routeName] = {
name: routeName,
paramKey
};
return acc;
}, {} as Record<string, { name: string; paramKey?: string }>);
/**
* Handles processing and routing of deep links in the application.
* Provides validation, error handling, and routing for deep link URLs.
@@ -69,30 +96,7 @@ export class DeepLinkHandler {
}
/**
* Maps deep link routes to their corresponding Vue router names and optional parameter keys.
*
* The paramKey is used to extract the parameter from the route path,
* because "router.replace" expects the right parameter name for the route.
* The default is "id".
*/
private readonly ROUTE_MAP: Record<
string,
{ name: string; paramKey?: string }
> = {
// note that similar lists are in src/interfaces/deepLinks.ts
claim: { name: "claim" },
"claim-add-raw": { name: "claim-add-raw" },
"claim-cert": { name: "claim-cert" },
"confirm-gift": { name: "confirm-gift" },
"contact-import": { name: "contact-import", paramKey: "jwt" },
did: { name: "did", paramKey: "did" },
"invite-one-accept": { name: "invite-one-accept", paramKey: "jwt" },
"onboard-meeting-members": { name: "onboard-meeting-members" },
project: { name: "project" },
"user-profile": { name: "user-profile" },
};
/**
* Parses deep link URL into path, params and query components.
* Validates URL structure using Zod schemas.
*
@@ -126,7 +130,7 @@ export class DeepLinkHandler {
// );
// Validate route exists before proceeding
if (!this.ROUTE_MAP[routePath]) {
if (!ROUTE_MAP[routePath]) {
throw {
code: "INVALID_ROUTE",
message: `Invalid route path: ${routePath}`,
@@ -144,7 +148,7 @@ export class DeepLinkHandler {
const params: Record<string, string> = {};
if (pathParams) {
// Now we know routePath exists in ROUTE_MAP
const routeConfig = this.ROUTE_MAP[routePath];
const routeConfig = ROUTE_MAP[routePath];
params[routeConfig.paramKey ?? "id"] = pathParams.join("/");
}
return { path: routePath, params, query };
@@ -170,7 +174,7 @@ export class DeepLinkHandler {
try {
// Validate route exists
const validRoute = routeSchema.parse(path) as DeepLinkRoute;
routeName = this.ROUTE_MAP[validRoute].name;
routeName = ROUTE_MAP[validRoute].name;
} catch (error) {
// Log the invalid route attempt
logConsoleAndDb(`[DeepLink] Invalid route path: ${path}`, true);