# Orval

## Introduction

* `orval` is able to generate client with appropriate type-signatures (TypeScript) from any valid OpenAPI v3 or Swagger v2 specification, either in `yaml` or `json` formats.

## Configuration

{% code title="orval.config.js" %}

```javascript
const { defineConfig } = require("orval");
module.exports = defineConfig({
  "famchest-api": {
    input: "https://dty6p2hiuf.us-east-1.awsapprunner.com/api-json",
    output: {
      mode: "tags-split",
      // generate type into a singgle file
      target: "./src/api/famchest.ts",
      // generate type into multiple files on same directory
      // schemas: "./lib/model",
      client: "react-query",
      prettier: true,
      // override the react-query fetching function
      override: {
        mutator: {
          path: "./src/api/fetcher.ts",
          name: "fetcher",
        },
      },
    },
  },
});

```

{% endcode %}

```bash
npx orval
```

## Generated File

* Type

{% code title="famchest.schemas.ts" %}

```typescript
export interface CreateProfileDto { [key: string]: unknown }

export interface PageDto {
  count: number;
}

export interface Profile {
  /** Profile ID */
  id: string;
  /** Shopify ID */
  shopifyId?: string;
  /** Gender */
  gender?: string;
  /** Phone */
  phone?: string;
  /** HKID */
  hkid?: string;
  /** Octopus */
  octopus?: string;
  /** Address 1 */
  address1?: string;
  /** Address 2 */
  address2?: string;
  /** Referrer */
  referrer?: string;
  /** Emergency Contact Name */
  emergencyContactName?: string;
  /** Emergency Contact Phone */
  emergencyContactPhone?: string;
  /** Beneficiary Name */
  beneficiaryName?: string;
  /** Beneficiary HKID */
  beneficiaryHkid?: string;
  /** Beneficiary Phone */
  beneficiaryPhone?: string;
  /** Email */
  email?: string;
  /** Famchest Username */
  famchestUsername?: string;
  /** Year of Birth */
  yearOfBirth?: number;
  /** Day of Birth */
  dayOfBirth?: number;
  /** Month of Birth */
  monthOfBirth?: number;
  /** Name */
  name?: string;
  /** Receive Promotion */
  receivePromotion?: boolean;
  /** Emergency Contact Relation */
  emergencyContactRelation?: string;
  /** Avatar Path */
  avatarPath?: string;
}
// ...
```

{% endcode %}

* React query hooks

  ```typescript
  /**
   * Generated by orval v7.8.0 🍺
   * Do not edit manually.
   * Famchest API
   * Famchest API description
   * OpenAPI spec version: 1.0
   */
  import { useQuery } from "@tanstack/react-query";

  import { fetcher } from ".././fetcher";

  import type { ErrorType } from ".././fetcher";
  import type {
    DataTag,
    DefinedInitialDataOptions,
    DefinedUseQueryResult,
    QueryClient,
    QueryFunction,
    QueryKey,
    UndefinedInitialDataOptions,
    UseQueryOptions,
    UseQueryResult,
  } from "@tanstack/react-query";

  type SecondParameter<T extends (...args: never) => unknown> = Parameters<T>[1];

  // the fetching function
  export const appControllerGetHello = (
    options?: SecondParameter<typeof fetcher>,
    signal?: AbortSignal,
  ) => {
    return fetcher<string>({ url: `/`, method: "GET", signal }, options);
  };

  // query key, mainly using api path as key
  export const getAppControllerGetHelloQueryKey = () => {
    return [`/`] as const;
  };

  // declare query option and apply query function and query key
  export const getAppControllerGetHelloQueryOptions = <
    TData = Awaited<ReturnType<typeof appControllerGetHello>>,
    TError = ErrorType<unknown>,
  >(options?: {
    query?: Partial<
      UseQueryOptions<
        Awaited<ReturnType<typeof appControllerGetHello>>,
        TError,
        TData
      >
    >;
    request?: SecondParameter<typeof fetcher>;
  }) => {
    const { query: queryOptions, request: requestOptions } = options ?? {};

    const queryKey = queryOptions?.queryKey ?? getAppControllerGetHelloQueryKey();

    const queryFn: QueryFunction<
      Awaited<ReturnType<typeof appControllerGetHello>>
    > = ({ signal }) => appControllerGetHello(requestOptions, signal);

    return { queryKey, queryFn, ...queryOptions } as UseQueryOptions<
      Awaited<ReturnType<typeof appControllerGetHello>>,
      TError,
      TData
    > & { queryKey: DataTag<QueryKey, TData, TError> };
  };

  // result type
  export type AppControllerGetHelloQueryResult = NonNullable<
    Awaited<ReturnType<typeof appControllerGetHello>>
  >;

  // error type
  export type AppControllerGetHelloQueryError = ErrorType<unknown>;

  // react query hook type
  export function useAppControllerGetHello<
    TData = Awaited<ReturnType<typeof appControllerGetHello>>,
    TError = ErrorType<unknown>,
  >(
    options: {
      query: Partial<
        UseQueryOptions<
          Awaited<ReturnType<typeof appControllerGetHello>>,
          TError,
          TData
        >
      > &
        Pick<
          DefinedInitialDataOptions<
            Awaited<ReturnType<typeof appControllerGetHello>>,
            TError,
            Awaited<ReturnType<typeof appControllerGetHello>>
          >,
          "initialData"
        >;
      request?: SecondParameter<typeof fetcher>;
    },
    queryClient?: QueryClient,
  ): DefinedUseQueryResult<TData, TError> & {
    queryKey: DataTag<QueryKey, TData, TError>;
  };
  export function useAppControllerGetHello<
    TData = Awaited<ReturnType<typeof appControllerGetHello>>,
    TError = ErrorType<unknown>,
  >(
    options?: {
      query?: Partial<
        UseQueryOptions<
          Awaited<ReturnType<typeof appControllerGetHello>>,
          TError,
          TData
        >
      > &
        Pick<
          UndefinedInitialDataOptions<
            Awaited<ReturnType<typeof appControllerGetHello>>,
            TError,
            Awaited<ReturnType<typeof appControllerGetHello>>
          >,
          "initialData"
        >;
      request?: SecondParameter<typeof fetcher>;
    },
    queryClient?: QueryClient,
  ): UseQueryResult<TData, TError> & {
    queryKey: DataTag<QueryKey, TData, TError>;
  };
  export function useAppControllerGetHello<
    TData = Awaited<ReturnType<typeof appControllerGetHello>>,
    TError = ErrorType<unknown>,
  >(
    options?: {
      query?: Partial<
        UseQueryOptions<
          Awaited<ReturnType<typeof appControllerGetHello>>,
          TError,
          TData
        >
      >;
      request?: SecondParameter<typeof fetcher>;
    },
    queryClient?: QueryClient,
  ): UseQueryResult<TData, TError> & {
    queryKey: DataTag<QueryKey, TData, TError>;
  };

  // react query hook implementation
  export function useAppControllerGetHello<
    TData = Awaited<ReturnType<typeof appControllerGetHello>>,
    TError = ErrorType<unknown>,
  >(
    options?: {
      query?: Partial<
        UseQueryOptions<
          Awaited<ReturnType<typeof appControllerGetHello>>,
          TError,
          TData
        >
      >;
      request?: SecondParameter<typeof fetcher>;
    },
    queryClient?: QueryClient,
  ): UseQueryResult<TData, TError> & {
    queryKey: DataTag<QueryKey, TData, TError>;
  } {
    const queryOptions = getAppControllerGetHelloQueryOptions(options);

    const query = useQuery(queryOptions, queryClient) as UseQueryResult<
      TData,
      TError
    > & { queryKey: DataTag<QueryKey, TData, TError> };

    query.queryKey = queryOptions.queryKey;

    return query;
  }
  ```

```typescript
```
