Open7

hey-api

nicopinnicopin
nicopinnicopin
openapi-ts.config
import {defineConfig} from '@hey-api/openapi-ts';

export default defineConfig({
    client: '@hey-api/client-axios',
    input: 'http://localhost:8000/openapi.json',
    output: 'src/client',
    types: {
        enums: false,
    },
    services: {
        asClass: true,
    }
});
nicopinnicopin

Nextjs SSR CSR

axiosのインターセプターをapp routerで適切に設定するにはSSRのレイアウトの中でCSRのコンポーネントを定義してGlobalConfigとして設定する方法がベター?

import "@fontsource/roboto/300.css";
import "@fontsource/roboto/400.css";
import "@fontsource/roboto/500.css";
import "@fontsource/roboto/700.css";
import "@fontsource/material-icons";
import {ReactNode} from "react";
import {SITE_NAME, SiteMetaConst} from "@/constants/SiteMetaConst";
import ClientGlobalConfig from "@/components/Layout/ClientGlobalConfig";


export const metadata = SiteMetaConst;
const RootLayout = ({children}: { children: ReactNode }) => {
    return (
        <html lang="en">
        <head>
            <title>{SITE_NAME}</title>
        </head>
        <body>
        <ClientGlobalConfig/>
        {children}
        </body>
        </html>
    );
};

export default RootLayout;
'use client'
import {FC} from "react";
import axios, {AxiosError} from "axios";
import {client} from "@hey-api/client-axios";

client.instance.interceptors.response.use(
    (res) => {
        return res
    },
    async (error: AxiosError) => {
        if (
            error.config &&
            error.response?.status === 401 &&
            // @ts-ignore
            error.response.data.detail === "Token expired" &&
            (error.config.retryCount ?? 0) < 3 &&
            !error.config.url?.endsWith("/api/auth/refresh-token")
        ) {
            // eslint-disable-next-line no-param-reassign
            error.config.retryCount = 1 + (error.config.retryCount ?? 0);
            try {
                await axios.get("/api/auth/refresh-token", {
                    responseType: "json",
                    withCredentials: true,
                    headers: {
                        "Content-Type": "application/json",
                    },
                });
                return await axios(error.config);
            } catch (e) {
                if (typeof window !== "undefined") {
                    const currentUrl = new URL(window.location.href);
                    const pathSegments = currentUrl.pathname.split("/");
                    const lang = pathSegments[1];
                    window.location.href = `/${lang}/auth/signin?redirect=${encodeURIComponent(
                        currentUrl.toString(),
                    )}`;
                }

                return Promise.reject(e);
            }
        }
        return Promise.reject(error);
    },
);

const ClientGlobalConfig: FC = () => {
    return <div/>
}

export default ClientGlobalConfig;
nicopinnicopin

Migration

before

import { defineConfig } from '@hey-api/openapi-ts';

function makeMethodNameFromSummary(str: string): string {
  return str
    .split(' ')
    .map((word, index) => {
      if (index === 0) {
        return word.toLowerCase();
      } else {
        return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
      }
    })
    .join('');
}

export default defineConfig({
  client: '@hey-api/client-axios',
  input: 'http://localhost:8000/openapi.json',
  output: 'src/client',
  types: {
    enums: false,
  },
  services: {
    asClass: true,
    methodNameBuilder: (operation) => {
      if (operation.summary) {
        return makeMethodNameFromSummary(operation.summary);
      }
      console.warn('Operation summary is not defined:', operation.name);
      return operation.name;
    },
  },
});

after

import { defaultPlugins, defineConfig } from '@hey-api/openapi-ts';

function makeMethodNameFromSummary(str: string): string {
	return str
		.split(' ') 
		.map((word, index) => {
			if (index === 0) {
				return word.toLowerCase();
			} else {
				return word.charAt(0).toUpperCase() + word.slice(1).toLowerCase();
			}
		})
		.join('');
}

export default defineConfig({
	client: '@hey-api/client-fetch',
	experimentalParser: true,
	input: 'http://localhost:8000/openapi.json',
	output: 'src/lib/client',
	plugins: [
		...defaultPlugins,
		{
			enums: false,
			name: '@hey-api/typescript'
		},
		{
			asClass: true,
			name: '@hey-api/sdk',
			methodNameBuilder: (operation) => {
				if (operation.summary) {
					return makeMethodNameFromSummary(operation.summary);
				}
				console.warn('Operation summary is not defined:', operation.id);
				return operation.id || 'unknown';
			}
		}
	]
});

nicopinnicopin

fetch config to throw error on status

import { createConfig } from '@hey-api/client-fetch';
const config = createConfig({
		throwOnError: true
	});
	client.setConfig(config);