From 2f7510839f8c81e51cd6c20c921fb0503cfd013a Mon Sep 17 00:00:00 2001 From: Mikkel Jakobsen Date: Thu, 21 Nov 2024 23:15:38 +0100 Subject: [PATCH] Enable goConfig to infer its return type By adding some extra typescript magic --- app/auth/token/refresh/route.ts | 2 +- app/page.tsx | 2 +- codegen.ts | 2 +- components/pages/searchPageLayout/helper.ts | 13 ++++++------- components/shared/searchFilters/helper.ts | 7 +++---- lib/config/config.ts | 11 ++++++++--- lib/config/resolvers/app.ts | 1 + lib/config/resolvers/search.ts | 2 -- lib/config/resolvers/service.unilogin.ts | 1 + lib/machines/search/useSearchMachineActor.tsx | 6 +++--- lib/session/oauth/uniloginClient.ts | 10 +++++----- 11 files changed, 30 insertions(+), 27 deletions(-) diff --git a/app/auth/token/refresh/route.ts b/app/auth/token/refresh/route.ts index b5b44053..710d9d77 100644 --- a/app/auth/token/refresh/route.ts +++ b/app/auth/token/refresh/route.ts @@ -16,7 +16,7 @@ const sessionTokenSchema = z.object({ }) export async function GET(request: NextRequest, response: NextResponse) { - const appUrl = goConfig("app.url") + const appUrl = goConfig("app.url") const session = await getSession() const frontpage = `${appUrl}/` diff --git a/app/page.tsx b/app/page.tsx index a6def975..ac4e0351 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -2,7 +2,7 @@ import Image from "next/image" import goConfig from "@/lib/config/config" -const wellknownUrl = goConfig>("service.unilogin.wellknown.url") +const wellknownUrl = goConfig("service.unilogin.wellknown.url") export default async function Home() { return (
("service.fbi.graphql.endpoint")]: { + [String(goConfig("service.fbi.graphql.endpoint"))]: { headers: { Authorization: `Bearer ${goConfig("token.adgangsplatformen.library")}`, }, diff --git a/components/pages/searchPageLayout/helper.ts b/components/pages/searchPageLayout/helper.ts index ca9a4937..0f04ab6f 100644 --- a/components/pages/searchPageLayout/helper.ts +++ b/components/pages/searchPageLayout/helper.ts @@ -4,7 +4,6 @@ import { ReadonlyURLSearchParams } from "next/navigation" import { getFacetMachineNames } from "@/components/shared/searchFilters/helper" import goConfig from "@/lib/config/config" -import { TConfigSearchFacets } from "@/lib/config/resolvers/search" import { SearchFiltersInput, SearchWithPaginationQuery } from "@/lib/graphql/generated/fbi/graphql" import { TFilters } from "@/lib/machines/search/types" import useSearchMachineActor from "@/lib/machines/search/useSearchMachineActor" @@ -18,29 +17,29 @@ export const getSearchQueryArguments = ({ currentPage: number facetFilters: SearchFiltersInput }) => { - const limit = goConfig("search.item.limit") + const limit = goConfig("search.item.limit") return { q: { all: q }, offset: currentPage * limit, limit: limit, filters: { - branchId: goConfig<`${number}`[]>("search.branch.ids"), + branchId: goConfig("search.branch.ids"), ...facetFilters, }, } } export const getFacetsForSearchRequest = (searchParams: ReadonlyURLSearchParams) => { - const facets = goConfig("search.facets") + const facets = goConfig("search.facets") const facetsMachineNames = getFacetMachineNames() return facetsMachineNames.reduce( (acc: TFilters, machineName) => { - const values = searchParams.getAll(facets[machineName].filter) + const values = searchParams.getAll(facets[machineName as keyof typeof facets].filter) if (values.length > 0) { return { ...acc, - [facets[machineName].filter]: [...values], + [facets[machineName as keyof typeof facets].filter]: [...values], } } return acc @@ -52,7 +51,7 @@ export const getFacetsForSearchRequest = (searchParams: ReadonlyURLSearchParams) export const getNextPageParamsFunc = ( currentPage: number ): GetNextPageParamFunction => { - const limit = goConfig("search.item.limit") + const limit = goConfig("search.item.limit") return ({ search: { hitcount } }) => { const totalPages = Math.ceil(hitcount / limit) diff --git a/components/shared/searchFilters/helper.ts b/components/shared/searchFilters/helper.ts index d84b8a9a..02269b86 100644 --- a/components/shared/searchFilters/helper.ts +++ b/components/shared/searchFilters/helper.ts @@ -3,7 +3,6 @@ import { AppRouterInstance } from "next/dist/shared/lib/app-router-context.share import { ReadonlyURLSearchParams } from "next/navigation" import goConfig from "@/lib/config/config" -import { TConfigSearchFacets } from "@/lib/config/resolvers/search" import { FacetFieldEnum, SearchFacetFragment } from "@/lib/graphql/generated/fbi/graphql" import { TContext, TFilters } from "@/lib/machines/search/types" @@ -44,14 +43,14 @@ export const sortByActiveFacets = (facet: SearchFacetFragment, selectedFilters: } export const getFacetMachineNames = () => { - const facets = goConfig>("search.facets") + const facets = goConfig("search.facets") return Object.keys(facets) as FacetFieldEnum[] } export const getFacetTranslation = (facetFilter: keyof TFilters) => { - const facets = goConfig("search.facets") + const facets = goConfig("search.facets") - return facets[facetFilter.toUpperCase() as keyof TConfigSearchFacets].translation || "" + return facets[facetFilter.toUpperCase() as keyof typeof facets].translation || "" } export const getActiveFilters = ( diff --git a/lib/config/config.ts b/lib/config/config.ts index a102b32a..216da9bd 100644 --- a/lib/config/config.ts +++ b/lib/config/config.ts @@ -13,7 +13,10 @@ const resolvers = { ...token, } -const retrieveValue = (key: keyof typeof resolvers) => { +type TResolvers = typeof resolvers +type TConfigKey = keyof TResolvers + +const retrieveValue = (key: TConfigKey): any => { if (key in resolvers) { if (typeof resolvers[key] !== "function") { return resolvers[key] @@ -24,8 +27,10 @@ const retrieveValue = (key: keyof typeof resolvers) => { return null } -const goConfig = (key: keyof typeof resolvers) => { - const value = retrieveValue(key) as TValue +const goConfig = ( + key: K +): TResolvers[K] extends () => infer R ? R : TResolvers[K] => { + const value = retrieveValue(key) if (!value && value !== 0) { throw new MissingConfigurationError(`Missing configuration for ${key}`) diff --git a/lib/config/resolvers/app.ts b/lib/config/resolvers/app.ts index bac69286..81162cf7 100644 --- a/lib/config/resolvers/app.ts +++ b/lib/config/resolvers/app.ts @@ -11,6 +11,7 @@ const app = { } } } + throw new Error("No app URL found.") }, } diff --git a/lib/config/resolvers/search.ts b/lib/config/resolvers/search.ts index 07ba0cb1..a5ea7c0b 100644 --- a/lib/config/resolvers/search.ts +++ b/lib/config/resolvers/search.ts @@ -51,6 +51,4 @@ const search = { }, } -export type TConfigSearchFacets = Record - export default search diff --git a/lib/config/resolvers/service.unilogin.ts b/lib/config/resolvers/service.unilogin.ts index fad93ff1..b98f820a 100644 --- a/lib/config/resolvers/service.unilogin.ts +++ b/lib/config/resolvers/service.unilogin.ts @@ -37,6 +37,7 @@ const serviceUnilogin = { if (process.env.UNILOGIN_SESSION_SECRET) { return process.env.UNILOGIN_SESSION_SECRET } + throw new Error("No unilogin session secret found.") }, } diff --git a/lib/machines/search/useSearchMachineActor.tsx b/lib/machines/search/useSearchMachineActor.tsx index 360d5dfc..b496bf25 100644 --- a/lib/machines/search/useSearchMachineActor.tsx +++ b/lib/machines/search/useSearchMachineActor.tsx @@ -14,9 +14,9 @@ import searchMachine from "./search.machine" const searchActor = createActor(searchMachine, { input: { - initialOffset: goConfig("search.offset.initial"), - searchPageSize: goConfig("search.item.limit"), - facetLimit: goConfig("search.facet.limit"), + initialOffset: goConfig("search.offset.initial"), + searchPageSize: goConfig("search.item.limit"), + facetLimit: goConfig("search.facet.limit"), }, }).start() diff --git a/lib/session/oauth/uniloginClient.ts b/lib/session/oauth/uniloginClient.ts index 056cb725..20d78eff 100644 --- a/lib/session/oauth/uniloginClient.ts +++ b/lib/session/oauth/uniloginClient.ts @@ -3,15 +3,15 @@ import { Issuer } from "openid-client" import goConfig from "@/lib/config/config" export const getOpenIdClientUniloginClientConfig = async () => { - const appUrl = await goConfig>("app.url") - const apiUrl = await goConfig>("service.unilogin.api.url") + const appUrl = goConfig("app.url") + const apiUrl = await goConfig("service.unilogin.api.url") return { - wellKnownUrl: await goConfig>("service.unilogin.wellknown.url"), + wellKnownUrl: await goConfig("service.unilogin.wellknown.url"), url: apiUrl, audience: apiUrl, - client_id: await goConfig>("service.unilogin.client-id"), - client_secret: await goConfig>("service.unilogin.client-secret"), + client_id: await goConfig("service.unilogin.client-id"), + client_secret: await goConfig("service.unilogin.client-secret"), scope: "openid", redirect_uri: `${appUrl}/auth/callback/unilogin`, post_logout_redirect_uri: appUrl,