-
Notifications
You must be signed in to change notification settings - Fork 8
Description
Implementation Plan: Static Route Schema & Framework Injection
Related User Story: #3715
Objective: This high-level goal will be achieved through the delivery of work described in the tasks below.
Deliver a new public module @equinor/fusion-framework-react-router that provides:
- A typed route DSL with metadata
- Static manifest generation at build time
- Framework injection into React Router v7 loaders
- Zero runtime cost and full TypeScript support
High-Level Tasks
Phase 1: Package Foundation & Core DSL
- Create New Package - Initialize
@equinor/fusion-framework-react-routerpackage structure - Define Core Types & DSL API - Implement
RouteNode,ParamSchema,SearchSchematypes and DSL functions (route,index,layout,prefix) - Implement DSL to React Router Conversion - Build
toReactRouter()function that convertsRouteNode[]toRouteObject[]
Phase 2: Framework Injection & Router Component
- Extend React Router Types - Augment React Router's
LoaderFunctionArgsto includecontext.framework - Implement Router Component - Create
<Router>component that injects framework instance into all loaders via React Router'scontext
Phase 3: Manifest Generation & CLI Integration
- Create Route Manifest Generator - Implement
extractRouteMetadata()function to extract route metadata fromRouteNode[] - Integrate with App Manifest Generation - Update
AppBuildManifestandcreateAppManifestFromPackage()to include optionalroutesfield - Integrate with Portal Manifest Generation - Update
PortalManifestBuildSchemato include optionalroutesfield - Add Route Validation - Implement validation and error reporting for route schemas
Phase 4: Type Safety & Developer Experience
- Implement Type-Safe Route Utilities - Create
generatePath()anduseParams()wrappers with route path inference - Integrate with App Config - Update
defineAppConfig()to acceptroutesparameter
Phase 5: Documentation & Examples
- Create Documentation - Write comprehensive README and API documentation
- Create Cookbook Example - Build cookbook demonstrating DSL usage with framework injection
Phase 6: Testing & Quality Assurance
- Unit Tests - Test DSL functions, conversion, and validation
- Integration Tests - Test Router component, framework injection, and manifest generation
Phase 7: Publishing
- Publish Package - Version, create changeset, publish to npm
Public API (Conceptual Examples)
routes.ts
import { Router, route, index, createRoutes } from '@equinor/fusion-framework-react-router';
import { defineAppConfig } from '@equinor/fusion-framework-cli/app';
export const routes = createRoutes([
index("./home.tsx", {
description: "Application home page",
search: {
view: { description: "UI view mode", enum: ["grid", "list"] }
}
}),
route("contracts/:contractId", "./contracts/view.tsx", {
description: "View a single contract",
params: {
contractId: { description: "Unique contract identifier" }
},
search: {
tab: { description: "Active tab", enum: ["details", "history", "files"] },
filter: { description: "Filter by status", enum: ["active", "archived"] }
}
})
]);contracts/view.tsx
import { useLoaderData, useParams, LoaderFn } from '@equinor/fusion-framework-react-router';
export const loader: LoaderFn = async ({ context }) => {
const client = context.framework.http.createClient('contracts');
const contract = await client.fetch('/contracts/123');
return { contract };
}
export default function ContractView() {
const { contract } = useLoaderData<typeof loader>();
const { contractId } = useParams();
return <div>{contract.title} (ID: {contractId})</div>;
}app.config.ts
// app.config.ts
export default defineAppConfig(() => ({ routes }));App.tsx
// App.tsx
<Router routes={routes} />Estimated Timeline
- Phase 1 (Foundation): 2-3 days
- Phase 2 (Framework Injection): 1-2 days
- Phase 3 (Manifest Generation): 2-3 days
- Phase 4 (Type Safety): 1-2 days
- Phase 5 (Documentation): 1-2 days
- Phase 6 (Testing): 2-3 days
- Phase 7 (Publishing): 1 day
Total: ~10-16 days
Notes
- Route extraction is optional - apps without routes continue to work
- Framework injection works for both DSL and legacy
RouteObject[]routes - Manifest generation happens at build time (no runtime cost)
- Type safety is critical for developer experience
Reactions are currently unavailable