1.1.3 β€’ Published 2 years ago

@fedorg/openapi-typescript-fetch v1.1.3

Weekly downloads
-
License
MIT
Repository
github
Last release
2 years ago

version(scoped) codecov

πŸ“˜οΈ openapi-typescript-fetch

A typed fetch client for openapi-typescript

Install

npm install openapi-typescript-fetch

Or

yarn add openapi-typescript-fetch

Features

Supports JSON request and responses

Usage

Generate typescript definition from schema

npx openapi-typescript https://petstore.swagger.io/v2/swagger.json --output petstore.ts

# πŸ”­ Loading spec from https://petstore.swagger.io/v2/swagger.json…
# πŸš€ https://petstore.swagger.io/v2/swagger.json -> petstore.ts [650ms]

Typed fetch client

import 'whatwg-fetch'

import { Fetcher } from 'openapi-typescript-fetch'

import { paths } from './petstore'

// declare fetcher for paths
const fetcher = Fetcher.for<paths>()

// global configuration
fetcher.configure({
  baseUrl: 'https://petstore.swagger.io/v2',
  init: {
    headers: {
      ...
    },
  },
  use: [...] // middlewares
})

// create fetch operations
const findPetsByStatus = fetcher.path('/pet/findByStatus').method('get').create()
const addPet = fetcher.path('/pet').method('post').create()

// fetch
const { status, data: pets } = await findPetsByStatus({
  status: ['available', 'pending'],
})

console.log(pets[0])

Typed Error Handling

A non-ok fetch response throws a generic ApiError

But an Openapi document can declare a different response type for each status code, or a default error response type

These can be accessed via a discriminated union on status, as in code snippet below

const findPetsByStatus = fetcher.path('/pet/findByStatus').method('get').create()
const addPet = fetcher.path('/pet').method('post').create()

try {
  await findPetsByStatus({ ... })
  await addPet({ ... })
} catch(e) {
  // check which operation threw the exception
  if (e instanceof addPet.Error) {
    // get discriminated union { status, data } 
    const error = e.getActualType()
    if (error.status === 400) {
      error.data.validationErrors // only available for a 400 response
    } else if (error.status === 500) {
      error.data.errorMessage // only available for a 500 response
    } else {
      ...
    }
  }
}

Middleware

Middlewares can be used to pre and post process fetch operations (log api calls, add auth headers etc)

import { Middleware } from 'openapi-typescript-fetch'

const logger: Middleware = async (url, init, next) => {
  console.log(`fetching ${url}`)
  const response = await next(url, init)
  console.log(`fetched ${url}`)
  return response
}

fetcher.configure({
  baseUrl: 'https://petstore.swagger.io/v2',
  init: { ... },
  use: [logger],
})

// or

fetcher.use(logger)

Server Side Usage

This library can be used server side with node-fetch

Node CommonJS setup

// install node-fetch v2
npm install node-fetch@2
npm install @types/node-fetch@2

// fetch-polyfill.ts
import fetch, { Headers, Request, Response } from 'node-fetch'

if (!globalThis.fetch) {
    globalThis.fetch = fetch as any
    globalThis.Headers = Headers as any
    globalThis.Request = Request as any
    globalThis.Response = Response as any
}

// index.ts
import './fetch-polyfill'

Utility Types

  • OpArgType - Infer argument type of an operation
  • OpReturnType - Infer return type of an operation
  • OpErrorType - Infer error type of an operation
  • FetchArgType - Argument type of a typed fetch operation
  • FetchReturnType - Return type of a typed fetch operation
  • FetchErrorType - Error type of a typed fetch operation
  • TypedFetch - Fetch operation type
import { paths, operations } from './petstore'

type Arg = OpArgType<operations['findPetsByStatus']>
type Ret = OpReturnType<operations['findPetsByStatus']>
type Err = OpErrorType<operations['findPetsByStatus']>

type Arg = OpArgType<paths['/pet/findByStatus']['get']>
type Ret = OpReturnType<paths['/pet/findByStatus']['get']>
type Err = OpErrorType<paths['/pet/findByStatus']['get']>

type FindPetsByStatus = TypedFetch<operations['findPetsByStatus']>

const findPetsByStatus = fetcher.path('/pet/findByStatus').method('get').create()

type Arg = FetchArgType<typeof findPetsByStatus>
type Ret = FetchReturnType<typeof findPetsByStatus>
type Err = FetchErrorType<typeof findPetsByStatus>

Utility Methods

  • arrayRequestBody - Helper to merge params when request body is an array
const body = arrayRequestBody([{ item: 1}], { param: 2})

// body type is { item: number }[] & { param: number }

Happy fetching! πŸ‘

ababacornacorn-jsxagent-baseajvansi-escapesacorn-globalsansi-regexansi-stylesanymatchacorn-walkansi-colorsarray-unionargasynckitargparseargvastral-regexbabel-jestbabel-plugin-istanbulbalanced-matchbabel-plugin-jest-hoistbabel-preset-current-node-syntaxbabel-preset-jestbrace-expansionbracesbrowser-process-hrtimebase64-jsbs-loggerblbinary-extensionsbrowserslistbuffer-fromcallsitesbserbuffercamelcasechalkchar-regexci-infocaniuse-litechardetchokidarcjs-module-lexercliuicli-cursorcocli-spinnerscolor-convertcolor-namecombined-streamconcat-mapconvert-source-mapcookiecli-widthcross-spawncssomcssstyledata-urlsdebugdecimal.jsdedentdeep-isclonecollect-v8-coveragedelayed-streamdetect-newlinecreate-requirediff-sequencesdir-globdeepmergediffdefaultsdomexceptiondoctrineemitteryemoji-regexescaladeelectron-to-chromiumescape-string-regexpeslint-scopeenquirereslint-utilseslint-visitor-keysespreeescodegenesqueryesrecurseestraverseesprimaesutilseventsexecaexpectfast-deep-equalfast-difffast-globfast-json-stable-stringifyfast-levenshteinexitfastqexternal-editorfile-entry-cachefill-rangefind-upfb-watchmanfast-url-parserform-datafs.realpathfunction-bindfunctional-red-black-treegensyncget-caller-filefiguresget-streamglobglob-parentglobalsglobbygraceful-fsgraphqlhashas-flagheaders-utilshtml-encoding-snifferflattedhttp-proxy-agenthttps-proxy-agenthuman-signalsiconv-liteflat-cacheignoreget-package-typeimport-freshimport-localimurmurhashinflightinheritshtml-escaperieee754is-ciis-core-moduleis-extglobis-fullwidth-code-pointis-generator-fnis-globignore-walkinquireris-numberis-potential-custom-element-nameis-streamis-typedarrayis-binary-pathisexeistanbul-lib-coverageis-interactiveistanbul-lib-reportis-unicode-supportedis-node-processistanbul-lib-instrumentjest-circusjest-configjest-diffjest-docblockjest-eachjest-environment-jsdomistanbul-lib-source-mapsjest-get-typejest-haste-mapistanbul-reportsjest-changed-filesjest-matcher-utilsjest-message-utiljest-mockjest-environment-nodejest-regex-utiljest-resolvejest-pnp-resolverjest-runnerjest-runtimejest-serializerjest-snapshotjest-utiljest-validatejest-watcherjest-leak-detectorjest-jasmine2js-tokensjest-resolve-dependenciesjsdomjsescjson-schema-traversejson-stable-stringify-without-jsonifyjson5js-yamljs-levenshteinlevnlocate-pathlodashjest-workerlodash.mergekleurlodash.clonedeeplru-cachelodash.truncatemake-errormakeerrormerge-streammerge2micromatchmime-dbmime-typesmimic-fnminimatchminimistmslevennatural-comparenode-fetchlog-symbolsnode-match-pathnode-modules-regexpmake-dirnormalize-pathnpm-run-pathnwsapionceonetimeoptionatornode-releasesp-locatep-tryparent-moduleparse5path-existspath-is-absolutepath-keynode-int64path-typemute-streampicomatchpiratespkg-dirprelude-lsprettier-linter-helperspretty-formatorapath-parsepslpicocolorsqueue-microtaskreact-isprogresspunycodepromptsregexpprequire-directoryresolveresolve-cwdresolve-fromreaddirpreusifyreadable-streamrun-parallelrxjsrestore-cursorsafer-buffersaxesrequire-from-stringsemvershebang-commandshebang-regexsignal-exitrun-asyncset-cookie-parserslashsource-mapsource-map-supportsafe-bufferstack-utilssisteransislice-ansisprintf-jsstrict-event-emitterstring-widthstring-lengthstrip-ansistrip-bomstrip-final-newlinestrip-json-commentsstatusesstream-eventssupports-colorsymbol-treesupports-hyperlinksstring_decoderterminal-linkstubstext-tabletablethroatthroughtmplto-fast-propertiesto-regex-rangetough-cookietr46tslibtsutilstype-checktype-detectteeny-requesttypedarray-to-bufferuniversalifyuri-jstest-excludetmptype-festurlgreyv8-compile-cachew3c-hr-timew3c-xmlserializerwalkerutil-deprecatewebidl-conversionswhatwg-encodingwhatwg-mimetypewhatwg-urlwhichword-wrapwrap-ansiwrappywrite-file-atomicwsxml-name-validatorxmlcharsy18nyallistv8-to-istanbulyargs-parserwcwidthp-limitoutvariantuuidynos-tmpdiryargs
1.1.3

2 years ago