Skip to content

Commit

Permalink
feat(client): Install orval, Query, Axios and Husky
Browse files Browse the repository at this point in the history
  • Loading branch information
clementprdhomme committed Oct 25, 2024
1 parent 6e67ba6 commit c517683
Show file tree
Hide file tree
Showing 14 changed files with 4,775 additions and 40 deletions.
2 changes: 2 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
cd ./cms && yarn config-sync export -y
cd ../client && yarn types && yarn lint --fix && yarn check-types && git add src/types/generated/
3 changes: 2 additions & 1 deletion client/.eslintignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.next
/node_modules
/public
/public
/src/types/generated/
1 change: 1 addition & 0 deletions client/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"next/core-web-vitals",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended",
"plugin:@tanstack/query/recommended",
"plugin:import/recommended",
"plugin:import/typescript"
],
Expand Down
11 changes: 10 additions & 1 deletion client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@
"version": "0.1.0",
"private": true,
"scripts": {
"prepare": "cd .. && husky",
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"types": "orval --config ./src/orval.config.ts",
"check-types": "tsc"
},
"dependencies": {
"@artsy/fresnel": "7.1.4",
Expand All @@ -18,7 +21,9 @@
"@radix-ui/react-slot": "1.1.0",
"@radix-ui/react-tooltip": "1.1.3",
"@t3-oss/env-nextjs": "0.11.1",
"@tanstack/react-query": "5.59.16",
"@types/mapbox-gl": "3.4.0",
"axios": "1.7.7",
"class-variance-authority": "0.7.0",
"clsx": "2.1.1",
"express": "4.21.1",
Expand All @@ -36,6 +41,7 @@
},
"devDependencies": {
"@svgr/webpack": "8.1.0",
"@tanstack/eslint-plugin-query": "5.59.7",
"@types/node": "22.7.6",
"@types/react": "18.3.1",
"@types/react-dom": "18.3.1",
Expand All @@ -47,7 +53,10 @@
"eslint-import-resolver-typescript": "3.6.3",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-prettier": "5.2.1",
"husky": "9.1.6",
"jiti": "1.21.6",
"orval": "7.2.0",
"pinst": "3.0.0",
"postcss": "^8",
"prettier": "3.3.3",
"prettier-plugin-tailwindcss": "0.6.8",
Expand Down
5 changes: 4 additions & 1 deletion client/src/app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Jost, DM_Serif_Text } from "next/font/google";
import { NuqsAdapter } from "nuqs/adapters/next/app";

import ReactQueryProvider from "@/app/react-query-provider";
import Head from "@/components/head";

import type { Metadata } from "next";
Expand Down Expand Up @@ -37,7 +38,9 @@ export default function RootLayout({
<html lang="en" className={`${jost.variable} ${dmSerifText.variable}`}>
<Head />
<body>
<NuqsAdapter>{children}</NuqsAdapter>
<ReactQueryProvider>
<NuqsAdapter>{children}</NuqsAdapter>
</ReactQueryProvider>
</body>
</html>
);
Expand Down
43 changes: 43 additions & 0 deletions client/src/app/react-query-provider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
"use client";

// Since QueryClientProvider relies on useContext under the hood, we have to put 'use client' on top
import { isServer, QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { PropsWithChildren } from "react";

function makeQueryClient() {
return new QueryClient({
defaultOptions: {
queries: {
// With SSR, we usually want to set some default staleTime
// above 0 to avoid refetching immediately on the client
staleTime: 60 * 1000,
},
},
});
}

let browserQueryClient: QueryClient | undefined = undefined;

function getQueryClient() {
if (isServer) {
// Server: always make a new query client
return makeQueryClient();
} else {
// Browser: make a new query client if we don't already have one
// This is very important, so we don't re-make a new client if React
// suspends during the initial render. This may not be needed if we
// have a suspense boundary BELOW the creation of the query client
if (!browserQueryClient) browserQueryClient = makeQueryClient();
return browserQueryClient;
}
}

export default function ReactQueryProvider({ children }: PropsWithChildren) {
// NOTE: Avoid useState when initializing the query client if you don't
// have a suspense boundary between this and the code that may
// suspend because React will throw away the client on the initial
// render if it suspends and there is no boundary
const queryClient = getQueryClient();

return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
}
28 changes: 28 additions & 0 deletions client/src/orval.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { defineConfig } from "orval";

export default defineConfig({
cms: {
input: {
target: "../../cms/src/extensions/documentation/documentation/1.0.0/full_documentation.json",
filters: {
tags: ["Topic", "Sub-topic", "Dataset", "Layer"],
},
},
output: {
target: "./types/generated/strapi.ts",
mode: "tags",
client: "react-query",
clean: true,
override: {
mutator: {
path: "./services/api.ts",
name: "API",
},
query: {
useQuery: true,
signal: true,
},
},
},
},
});
25 changes: 25 additions & 0 deletions client/src/services/api.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import Axios, { AxiosError, AxiosRequestConfig } from "axios";

export const AXIOS_INSTANCE = Axios.create({ baseURL: process.env.NEXT_PUBLIC_API_URL });

export const API = <T>(config: AxiosRequestConfig, options?: AxiosRequestConfig): Promise<T> => {
// eslint-disable-next-line import/no-named-as-default-member
const source = Axios.CancelToken.source();
const promise = AXIOS_INSTANCE({
...config,
...options,
cancelToken: source.token,
}).then(({ data }) => data);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
promise.cancel = () => {
source.cancel("Query was cancelled");
};
return promise;
};

export type BodyType<BodyData> = BodyData;

export type ErrorType<Error> = AxiosError<Error>;

export default API;
Loading

0 comments on commit c517683

Please sign in to comment.