* Initial commit * routingForm to Booking a particular team member working * Happy path working * Fixes * Fix router query params forwarding * Add basicConfig within app * Tests * More tests * Update packages/app-store/routing-forms/components/SingleForm.tsx Co-authored-by: Omar López <zomars@me.com> --------- Co-authored-by: Omar López <zomars@me.com> Co-authored-by: Benny Joo <sldisek783@gmail.com>
70 lines
1.9 KiB
TypeScript
70 lines
1.9 KiB
TypeScript
"use client";
|
|
|
|
import type { App_RoutingForms_Form } from "@prisma/client";
|
|
import type { z } from "zod";
|
|
|
|
import type { FormResponse, Route, SerializableForm } from "../types/types";
|
|
import type { zodNonRouterRoute } from "../zod";
|
|
import { getQueryBuilderConfigForFormFields } from "./getQueryBuilderConfig";
|
|
import { isFallbackRoute } from "./isFallbackRoute";
|
|
import isRouter from "./isRouter";
|
|
import { evaluateRaqbLogic, RaqbLogicResult } from "./evaluateRaqbLogic";
|
|
|
|
export function findMatchingRoute({
|
|
form,
|
|
response,
|
|
}: {
|
|
form: SerializableForm<App_RoutingForms_Form>;
|
|
response: Record<string, Pick<FormResponse[string], "value">>;
|
|
}) {
|
|
const queryBuilderConfig = getQueryBuilderConfigForFormFields(form);
|
|
|
|
const routes = form.routes || [];
|
|
|
|
let chosenRoute: Route | null = null;
|
|
|
|
const fallbackRoute = routes.find(isFallbackRoute);
|
|
|
|
if (!fallbackRoute) {
|
|
throw new Error("Fallback route is missing");
|
|
}
|
|
|
|
const routesWithFallbackInEnd = routes
|
|
.flatMap((r) => {
|
|
// For a router, use it's routes instead.
|
|
if (isRouter(r)) return r.routes;
|
|
return r;
|
|
})
|
|
// Use only non fallback routes
|
|
.filter((route) => route && !isFallbackRoute(route))
|
|
// After above flat map, all routes are non router routes.
|
|
.concat([fallbackRoute]) as z.infer<typeof zodNonRouterRoute>[];
|
|
|
|
for (const route of routesWithFallbackInEnd) {
|
|
if (!route) {
|
|
continue;
|
|
}
|
|
|
|
const responseValues: Record<string, FormResponse[string]["value"]> = Object.fromEntries(
|
|
Object.entries(response).map(([uuid, { value }]) => [uuid, value])
|
|
);
|
|
|
|
const result = evaluateRaqbLogic({
|
|
queryValue: route.queryValue,
|
|
queryBuilderConfig,
|
|
data: responseValues,
|
|
});
|
|
|
|
if (result === RaqbLogicResult.MATCH || result === RaqbLogicResult.LOGIC_NOT_FOUND_SO_MATCHED) {
|
|
chosenRoute = route;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!chosenRoute) {
|
|
return null;
|
|
}
|
|
|
|
return chosenRoute;
|
|
}
|