Code Monkey home page Code Monkey logo

openapi-client-axios's People

Contributors

alleksei37 avatar anttiviljami avatar core-entin avatar dankeroni avatar dannyhaak avatar davidnewcomb avatar dependabot[bot] avatar dremendes avatar dumdiedum avatar frmrm avatar genehack avatar gfortaine avatar gterral avatar henrycunh avatar jeongy-cho avatar jfpimentel avatar johnbeech avatar josx avatar leeroyrose avatar lgtm-migrator avatar lmarvaud avatar mdwheele avatar npdev453 avatar nponeccop avatar pas-mike avatar rowrowrowrow avatar sunkan avatar w3nl avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

openapi-client-axios's Issues

When resolving baseURLVariables, enum should be optional and not required

It looks like when substituting base url variables in the server object, an enum array is required. The spec says enum is optional and not required in server object. The logic should be when the enum is present in the server definition: check variable is in enum values list. If enum is not present, the variable should be substituted like a normal path variable.

Thanks

Release v4.1 to NPM?

Hello! I was looking to use the new transformOperationMethod option that is in your official docs, but it seems it has not been released to NPM yet. What are the plans for the 4.1 release?

Thanks!

Fresh installation of any packages dependent `openapi-client-axios` are broken

Hi @anttiviljami,

yesterday one of my experemental package was broken when was installed freshly (without package-lock.json and node_modules) with next error:

     TypeError: Cannot read property 'dereference' of undefined

      at crawl (node_modules/@apidevtools/json-schema-ref-parser/lib/dereference.js:44:15)
      at Object.dereference [as default] (node_modules/@apidevtools/json-schema-ref-parser/lib/dereference.js:19:22)
      at OpenAPIClientAxios.initSync (node_modules/openapi-client-axios/client.js:206:34)
      at Object.B.default (<index.js>:42:25)
      at new e.B (<index.js>:384:11)

After some drilling of some sources I detect that reasons of the problem is in:

  • json-schema-ref-parser library update from 9.0.6 to 9.0.7
    release 9.0.7
    "breakin" change (but not breakin by a docs)

  • openapi-client-axios incorrect incorrect usage of derefence from that library
    derefence has a second options param that type is $RefParserOptions and was never marked as optional

  • npm install that does not respect package-lock.json of dependencies
    npm/npm#19458

So, that error can be catched by anyone who will install openapi-client-axios in new projects or while force deps upgrade,
by that reason asking to fix it asap.

PR with fix: #54

Improve Lodash imports for tree-shaking

Hi. I was glancing through this lib to evaluate whether it might be a good fit for our app, and I noticed that it currently imports Lodash as a default import:

import _ from "lodash"

This will likely cause the entire Lodash library to be pulled in and increase bundle sizes for apps. It would probably be better if the individual functions were imported seperately, like import flatMap from "lodash/flatMap".

Should I automatically see types when using JS?

Great initiate here, thank you.

Question - I'm using JS and followed the docs, but can't see any types suggestion in vscode. Here what I've done:

const mailerAPI = new OpenAPIClientAxios({
    definition: path.join(__dirname, '../openapi.json'),
  });
  await mailerAPI.init();
  mailerAPI.{expected to see methods here but nothing from openapi operations appear here}

Should I run typegen manually? What is the workflow for JS scenario (not TS) given that most IDE knows to conclude d.ts file definitions even when coding with JS?

Typegen: typegen can't assign parameter types to Operation methods if operationId includes non-alphanumeric characters

I've been trying to work with the Riot API, (openapi schema here: http://www.mingweisamuel.com/riotapi-schema/openapi-3.0.0.json) and found that not only method names generated by typegen weren't escaped properly (ie #26) but also typegen could not assign proper types to each method.

I found that the dtsgenerator dependency sanitizes/normalizes operation id names when parsing schema to path names so path names for operations are not the same anymore, and thus cant be found by typegen.

Example:
"tft-league-v1.getLeagueEntriesForSummoner" is sanitized as "tft_league_v1.getLeagueEntriesForSummoner"

So when typegen does a filter for the param paths on an operation, there are no results.

A fix would be to do the same transformation on operationId when searching for types.

Solution:

// on src/typegen/typegen.ts
import {normalizeTypeName} from "@anttiviljami/dtsgenerator/dist/core/typeNameConvertor"

  // normalized operationId
  const normalizedOpId = normalizeTypeName(operationId)
  // parameters arg
  const parameterTypePaths = _.chain([
    _.find(exportTypes, { schemaRef: `#/paths/${normalizedOpId}/pathParameters` }),
    _.find(exportTypes, { schemaRef: `#/paths/${normalizedOpId}/queryParameters` }),
    _.find(exportTypes, { schemaRef: `#/paths/${normalizedOpId}/headerParameters` }),
    _.find(exportTypes, { schemaRef: `#/paths/${normalizedOpId}/cookieParameters` }),
  ])
    .filter()
    .map('path')
    .value();
// and similar transformation for request body type and response type

Swagger 2 support

Is it possible integrate this client to the previous version swagger?

Typegen: The method names in OperationMethods are not escaped properly

Typegen output code breaks if an operationid contains a special character like .

sad code

Can be fixed by by making operationMethod be

var operationMethod =
        methodName.replace(/[\.,-\/#!$%\^&\*;:{}=\-_`~()\+\s]/g,'_') +
        '(\n' +
        operationArgs
            .map(function (arg) {
                return indent_string_1.default(arg, 2);
            })
            .join(',\n') +
        '  \n): ' +
        returnType;```

inside generateMethodForOperation

I would make a PR for it but it seems the repo went into oblivion

error with dependencies // jsdevtools

Hi all,
I've got a system up an running using Vue.js 3.0.5 and Vite as a build system.
As I need to use a Swagger API in my project I thought it might be a good deal using this openapi-client-axios.
Actually I get an error as soon as I import the client:

import OpenAPIClientAxios from 'openapi-client-axios'
const api = new OpenAPIClientAxios({ definition: 'api.json' })
api.init()

These lines occur the error message:

[vite] new dependencies found: openapi-client-axios, updating...
 > node_modules/@jsdevtools/ono/esm/types.js: error: No matching export for import "inspect"
    1 │ import { inspect } from "util";
      ╵          ~~~~~~~

[vite] error while updating dependencies:
Error: Build failed with 1 error:
node_modules/@jsdevtools/ono/esm/types.js:1:9: error: No matching export for import "inspect"

Is it possible that some of the dependencies or this entire project are not ready for Vue 3 or what am I doing wrong?
Thanks a lot.

typegen - how to actually use generated OpenAPI type definitions ?

There is documentation on calling the actual client methods, but there doesn't seem to be any reference how to deal with the result of the client's response as the actual response type, nor how to import and use these types. The entire purpose of generating these OpenAPI types for me is to actually be able to use these types throughout my code, not just have a typed client with typed methods?

Please provide documentation on how to use said type definitions and actually handle the response code. There seems to be no way to import or use any of the response types.

Given the (slightly revised for example) code below:

import { Client as ApiClient } from '@/types/apiTypes'
const api = new OpenAPIClientAxios({ definition: 'http://localhost:8342/openapi.json' })

export async function apiClient() {
  return await api.getClient<ApiClient>()
}

const client = await apiClient()

const result = await client.readReport({ report_type: 'blah', report_id: 'test' })

if (typeof result.data === Components.Schemas.ReportOut) {
    console.log(result.data.details)
    console.log(result.data)
}
ERROR in utils/api.ts:19:23
TS2304: Cannot find name 'Components'.

ERROR in utils/api.ts:20:64
TS2339: Property 'details' does not exist on type 'ReportOut | HTTPValidationError'.
  Property 'details' does not exist on type 'HTTPValidationError'.

How will I be able to type check that report.data is a ReportOut type when it is in a nested namespace I cannot refer to? HTTPValidationError is returned if the response is not successful FYI. I could use "as any" but then I lose any type safety with result.data. I want to be able to use the API's ReportOut type throughout my code.

baseURL not seems to be parsed from definition

Currently, I need this code. (Backend is fastify-swagger.)

import OpenAPIClientAxios from 'openapi-client-axios'

import { Client } from '../types/openapi'

export const apiURL =
  process.env.baseURL || `http://localhost:${process.env.SERVER_PORT}`

export const apiDefintionURL = `${apiURL}/api/doc/json`

export const apiClient = new OpenAPIClientAxios({
  definition: apiDefintionURL,
})

// eslint-disable-next-line import/no-mutable-exports
export let api: Client

export async function initAPI() {
  api = await apiClient.init<Client>()
  api.defaults.baseURL = apiURL
  return api
}

I did take a look at source as well; and operation.servers[0] or targetServer seems to be required, regardless of definition...

Upgrading to axios version 0.20.0 breaks generated `Bearer` Authorization token method client

I upgraded from

-    "axios": "^0.19.2",
+    "axios": "^0.20.0",

And after that, my openapi calls that use the Bearer Authorization header token are consistently returning 403. Inspecting the network traffic it seems that after the axios upgrade, my generated axios client no longer is sending the required Authorization header at all. Is anyone else experiencing this? Is there a known workaround or is there a known regression with axios v0.20.0? Let me know if I can provide additional information to help demonstrate the issue I am encountering.

I have a slightly different use case, could I use your library to do what I want?

My use case:
I'd like to fetch the swagger.json at webpack compile time, and deliver it as a constant to my app. Then I can create a singleton client from that constant. I already have that working nicely here using swagger-js as a client.

What I want to do next:
I want to write a script to generate a .d.ts at webpack compile time (for developer's IntelliSense). Your project is already written in typescript, but swagger-js is not. Do you know how much work it would be to read in a definition, and output a type definition file to document the run-time client?

If you want to add that to your client, I can try to make sure it's compatible.

typegen fails if multiple remote/local references are used in "responses"

This is a bug report.

Thanks for creating great library 👍

I am trying to use typegen on some swagger.yaml files.
Those API definitions leverage remote/local reference (e.g. $ref: "path/to/entity") a lot, to minimize duplication of codes.

As far as I tested, typegen works finely with such remote/local references, ... except references in responses fields 😭
Those API definitions work finely with other Swagger-based tools (e.g. Swagger editor and Redoc), so I suspect this is an issue in openali-client-axios-typegen.

versions

  • typegen: 1.0.7

What happend

The below is a reproducible swagger file definitions.

We prepare 2 files.

  • swagger.yaml
  • shared-api-components.yaml

swagger.yaml

openapi: "3.0.0"
info:
  version: 0.66.7
  title: My API
servers: []
paths:
  /login:
    post:
      summary: login
      security: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: string
      responses:
        200:
          $ref: "./shared-components.yaml#/responses/LoginSuccess"
        503:
          $ref: "./shared-api-components.yaml#/responses/ServiceUnavailable"

shared-api-components.yaml

schemas:
  ErrorCode:
    type: string
    enum:
      - Unauthorized
      - UnderMaintenance
  ErrorUnauthorizedApi:
    type: object
    properties:
      errors:
        type: array
        items:
          $ref: "#/schemas/ErrorCode"
  ErrorUnderMaintenance:
    type: object
    properties:
      errors:
        type: array
        items:
          $ref: "#/schemas/ErrorCode"
responses:
  ErrorUnauthorizedApi:
    content:
      application/json:
        schema:
          $ref: "#/schemas/ErrorUnauthorizedApi"
  ErrorUnderMaintenance:
    content:
      application/json:
        schema:
          $ref: "#/schemas/ErrorUnderMaintenance"

Then, run typegen swagger.yaml > foo.d.ts and we will got

(node:630) UnhandledPromiseRejectionWarning: Error: The $ref targets root is not found: #/paths/~1login/post/responses/503/content/application~1json/schema/properties/errors/items
    at ReferenceResolver.<anonymous> (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/@anttiviljami/dtsgenerator/dist/core/referenceResolver.js:105:35)
    at step (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/tslib/tslib.js:136:27)
    at Object.next (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/tslib/tslib.js:117:57)
    at /usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/tslib/tslib.js:110:75
    at new Promise (<anonymous>)
    at Object.__awaiter (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/tslib/tslib.js:106:16)
    at ReferenceResolver.resolve (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/@anttiviljami/dtsgenerator/dist/core/referenceResolver.js:26:24)
    at DtsGenerator.<anonymous> (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/@anttiviljami/dtsgenerator/dist/core/dtsGenerator.js:22:50)
    at step (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/tslib/tslib.js:136:27)
    at Object.next (/usr/local/lib/node_modules/openapi-client-axios-typegen/node_modules/tslib/tslib.js:117:57)

Note

I observed some cases where typegen runs successfully with references on some cases.

Case 1. Limit the occurence of remote reference in responses to 1.

In swagger.yaml,

      responses:
        # 401:
        #  $ref: "swagger-api-components.yaml#/responses/ErrorUnauthorizedApi"
        503:
          $ref: "swagger-api-components.yaml#/responses/ErrorUnderMaintenance"

But this is not desirable, since I want to use remote reference/local reference to minimize code duplication.

Case 2. Limit the occurence of same local reference in external files to 1.

In shared-api-components.yaml, changed like below

schemas:
  ErrorCode:
    type: string
    enum:
      - Unauthorized
      - UnderMaintenance
  ErrorUnauthorizedApi:
    type: object
    properties:
      errors:
        type: array
        items:
          $ref: "#/schemas/ErrorCode"
  ErrorUnderMaintenance:
    type: object
    properties:
      errors:
        type: array
        items:
          type: string
          # HERE:  Removed local reference that already used above.
          # $ref: "#/schemas/ErrorCode"
responses:
  ErrorUnauthorizedApi:
    content:
      application/json:
        schema:
          $ref: "#/schemas/ErrorUnauthorizedApi"
  ErrorUnderMaintenance:
    content:
      application/json:
        schema:
          $ref: "#/schemas/ErrorUnderMaintenance"

But this is not desirable, since I want to use remote reference/local reference to minimize code duplication.

Global headers

Is there a way to initialize a client with global headers so that you don't have to pass the same one for each request?

Add support for other parameter types (query, header, cookie ...)

The OpenAPIv3 spec supports describing other types of parameters including query and header.

I have an openapi v3 spec that includes some of these. I'd love to be able to pass them directly in the pathParams and have the client automatically serialize them according to the spec.

Example:

paths:
  /systems:
    get:
      summary: List all Systems
      operationId: getSystems
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            format: int32
            default: 300
        - name: offset
          in: query
          schema:
            type: integer
            format: int32
  /entity_types:
    get:
      summary: List all Entity Types
      operationId: getEntityTypes
      parameters:
        - name: filters
          in: query
          style: deepObject
          explode: true
          schema:
            type: object
            properties:
              parent_id:
                type: string
                format: uuid
              data_visibility:
                type: string
                enum: [public, private, shared_ownership]

client.getSystems({limit: 10}) results in GET /systems?limit=10

client.getEntityTypes({filters: {data_visibility: 'public'}}) results in GET /entity_types?filters[data_visibility]=public

We currently need to manually create an AxiosRequestConfig for every request that includes parameters that are not path parameters.

Date-time Type

Hello, does the client handles type conversions like date-time?
endDate?: string; // date-time

typegen response format is unexpected

I have an openapi json file with responses for operations defined like this:

 "responses": {
                    "404": {
                        "description": "Not found"
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
...

When I run typegen on this client it seems to generate an invalid <MY_PATH> file.

It exports the resources fine with a dollar sign preceding the numbers

    namespace Responses {
      export type $200 = Components.Schemas.HospitalUtilization;
      export type $422 = Components.Schemas.HTTPValidationError;
    }

But then the generated response does not have the preceding dollarsign, which is invalid typescript and doesn't reference the generated code properly

    get(
      parameters?: Parameters<Paths.<MY_PATH>.PathParameters>,
      data?: any,
      config?: AxiosRequestConfig  
    ): OperationResponse<Paths.<MY_PATH>.Responses.200 | Paths.<MY_PATH>.Responses.422>
  }

Does anyone else run into this issue? If I find and replace all of these with the preceding dollar sign it seems to work fine.

The other method of generating a client- directly from my openapi.json works as well but I was hoping to switch to the typegen method.

Use fetch instead of axios as HTTP client

Is it possible to use the fetch API as the HTTP client instead of axios? In places where the fetch API is available (e.g., browser), I'd like to use it instead of including another HTTP client library.

Using cross-fetch allows us to use the same fetch API across all platforms (e.g., browser, node.js and React Native).

Thanks!

METHOD mismatch between config and axios request

for a function called createProductManufacturer which is method POST, in the config element the method attribute is right but the request is performed using method GET.

tested call by over paths[].post() and createProductManufacturer()

doing further research

Setting headers manually does not override initial headers

I'm not completely sure if this is bug or desired feature, but behaviour when setting headers manually for one request is (atleast in this case) weird.

Expected behaviour

Manually set headers overrides initial headers:
authorization: 'Bearer token'

Actual behaviour

Manually set headers are joined to initial headers:
authorization: 'initial header, Bearer token'

Steps to reproduce

const config = {
    definition: definition,
    axiosConfigDefaults: {
      headers: {
        authorization: 'initial header',
      },
    },
  };

const api  = new OpenAPIClientAxios(config);
api.withServer({ url });
await api.init();
const client = await api.getClient();

client.postSomething(null, data, { 
    headers: { 
      authorization: 'Bearer token' 
    } 
  }
);

Issue with multipart/form-data requests

Working with a image upload endpoint and noticed the generated client do not work as expected for multipart/form-data requests.

After some debugging it seems like the client creates a new FormData object and appends the files in the wrong way.

From the generated code:

localVarFormParams.append('files', files.join(COLLECTION_FORMATS.csv));

This will produce a request containing "[Object File], [Object File]..." in the body.

The correct way should be (tried it out and worked as expected) to something like

files.forEach((f: File) => {
  localVarFormParams.append('files[]', f));
})

This will produce the correct request body as also demonstrated here.

Im using the following OpenAPI definition for the endpoint:

"/upload": {
      "post": {
        "tags": [
          "Upload"
        ],
        "requestBody": {
          "description": "File upload",
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "properties": {
                  "files": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {...}
      }
    }
  }

Schema in query - results in weird URL

Hello, I am struggling a bit to get this to work. I am using the following PHP package to make filters:
https://github.com/spatie/laravel-query-builder

This expects, by default, to have a filter[filter_name] style URL parameter for searching.

I have the following specs:

Endpoint:

/api/integration-contacts:
    get:
      tags:
        - external
      summary: Gets a list of contacts in the system
      operationId: ListContacts
      description: |
        Searches all contacts in the system
      parameters:
        - in: query
          name: filter
          schema:
            $ref: '#/components/schemas/UserIntegrationSettingsContactsFilter'
      responses:
        '200':
          description: search results matching criteria
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserIntegrationSettingsContact'

Filter:

    UserIntegrationSettingsContactsFilter:
      type: object
      properties:
        id:
          type: string
          format: uuid
        user_integration_settings_id:
          type: string
          format: uuid

I have the following action:


        readList({commit}, filter) {
            commit('setIsLoadingList', true);

            return api_server.getClient()
                .then((client) => {
                    client.ListContacts(filter)
                        .then((list) => {
                            commit("setListData", list.data.data)
                        })
                        .catch((error) => {
                            console.log(error);
                        })
                        .finally(() => {
                            commit('setIsLoadingList', false)
                        });
                })
        },

Where the filter parameter is equal to:

{
     filter: {
        user_integration_settings: "someuuid"
     }
}

This produces the following URL:
http://api.my-url.local/api/integration-contacts?filter=%5Bobject%20Object%5D

The expected url is:
http://api.my-url.local/api/integration-contacts?filter[user_integration_settings_id]=someuuid

Any advice on how to get this to work?

use variables in baseURL

Hi,

I use a OpenAPI file with variables in servers url :

servers:
 url: https://api.{region}.domain.com/api/v1
  variables:
    region:
      default: eu-west-2
      enum: [eu-west-2, us-east-2, us-west-1]
 url: https://api.{region}.domain.hk/api/v1
  variables:
    region:
      default: cn-southeast-1
      enum: [cn-southeast-1]

When I use the getBaseURL() function, it returns this :

https://api.{region}.domain.com/api/v1

Is there a way to pass parameters in order to build the baseURL with the {region}, or at least the default value?

Thanks

Use it with an existing axios instance

Hello,
I try to use this tool in an existing app. It already uses an axios instance in JWTService Class to handle auth.
Is there a way to use the existing axios instance in the openApiClient instance rather than create a new one.

Thx

Missing source maps

Hello,

My app uses webpack and source-map-loader. When I'm trying to use this package, I get the following warning during compilation. This is happening because JS files inside openapi-client-axios have //# sourceMappingURL=<path> specified at the bottom, but source maps are not being distributed inside this NPM package.

Module Warning (from ./node_modules/source-map-loader/dist/cjs.js):
Failed to parse source map from 'C:\Users\User\app\node_modules\openapi-client-axios\index.js.map' file: Error: ENOENT: no such file or directory, open 'C:\Users\User\app\node_modules\openapi-client-axios\index.js.map'
 @ ./src/context/ClientContext.tsx 32:0-58 75:23-41
 @ ./src/context/index.ts 4:0-32 4:0-32
 @ ./src/index.tsx 21:0-103 30:25-39 31:32-46 32:34-54 33:36-56

Could you fix your bundling process to remove this line or actually include source maps?

Thanks!

Initialize client using typegen type, excluding openapi definition

I was wondering if there is a way that I am able to initialize a client without providing the OpenAPIClientAxios a definition when I've already got a generated type using typegen?

My issue is that the definition will not be public, so I cannot access it at runtime.

const api = new OpenAPIClientAxios({ definition: './oc-openapi.json' }); // Don't want this definition to be passed
api.withServer(OcOpenApiClient.environments[environment]);
api.getClient<Client>().then(client => OcOpenApiClient.instance = client);

Data Validation?

This is more of a question/feature request than an "issue".

Does the library perform validation on the input before sending it to the server?

For example given field like that

"username": {
    "type": "string",
    "description": "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only.",
    "pattern": "^[\\w.@+-]+\\Z",
    "maxLength": 150
}                  },

Would the library reject an input the exceed 150 character or doesn't match the pattern?

Typegen generated responses contains errors which are thrown and not returned.

Say I have this path:

"/auth": {
  "post": {
    "description": "Autentification d'un utilisateur",
    "operationId": "auth.auth",
    "security": [],
    "requestBody": {
      "content": {
        "application/json": {
          "schema": {
            "$ref": "#/components/schemas/authLogin"
          }
        },
        "application/x-www-form-urlencoded": {
          "schema": {
            "$ref": "#/components/schemas/authLogin"
          }
        }
      }
    },
    "responses": {
      "200": {
        "description": "Auth ok",
        "content": {
          "application/json": {
            "schema": {
      	"$ref": "#/components/schemas/authToken"
            }
          }
        }
      },
      "400": {
        "description": "Bad request",
        "content": {
          "application/json": {
            "schema": {
      	"$ref": "#/components/schemas/error"
            }
          }
        }
      },
      "401": {
        "description": "Bad Auth token",
        "content": {
          "application/json": {
            "schema": {
      	"$ref": "#/components/schemas/error"
            }
          },
        }
      }
    }
  }
},

The error type is this:

      "error": {
        "type": "object",
        "required": ["error"],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/non_empty_string"
          }
        },
        "example": {
          "error": "Email and or Password invalid."
        }
      },

typegen will generate this:

  /**
   * auth.auth - Autentification d'un utilisateur
   */
  'authAuth'(
    parameters?: undefined | null,
    data?: Paths.AuthAuth.RequestBody,
    config?: AxiosRequestConfig
  ): OperationResponse<
    | Paths.AuthAuth.Responses.$200
    | Paths.AuthAuth.Responses.$400
    | Paths.AuthAuth.Responses.$401
  >;

But only Paths.AuthAuth.Responses.$200 will ever be returned by client.authAuth as all status codes outside of 200..300 generate an exception. (see lib/adapters/xhr.js for example)

I think only the responses in the 2xx range should be added there. If TypeScript ever gets a "throws" keyword to describe what a function can throw, then they can be added back in there, but adding it as the return values feels wrong.

set transformResponse in axiosConfigDefaults

i want to do some processing everytime I gets api response, so I set a function in transformResponse in axiosConfigDefaults, which takes data as param and return data as it is. After applying the config, the response I got from apiclient changed to same as the data transformResponse function received. I think it is setting transformResponse overwrites the openapi-client's behavior of processing the response. I wonder what is the way (if any) to set a global response interceptor/function? thanks~

Nuxt integration

Thanks for the great job.
Is integration possible with NUXT and in particular with auth_next? (@nuxtjs/auth-next, @nuxtjs/axios)

thank you

type AxiosRequestConfig is not compatible with the one provided directly by axios.

I am converting some code base to typescript, and I scratched my head for something like half an hour with this error:

TS2345: Argument of type '(config: AxiosRequestConfig) => AxiosRequestConfig' is not assignable to parameter of type '(value: AxiosRequestConfig) => AxiosRequestConfig | Promise<AxiosRequestConfig>'.
  Types of parameters 'config' and 'value' are incompatible.
    Type 'import("/home/mat/work/api-sig-elig/admin/node_modules/openapi-client-axios/node_modules/axios/index").AxiosRequestConfig' is not assignable to type 'import("/home/mat/work/api-sig-elig/admin/node_modules/axios/index").AxiosRequestConfig'.
      Types of property 'adapter' are incompatible.
        Type 'import("/home/mat/work/api-sig-elig/admin/node_modules/openapi-client-axios/node_modules/axios/index").AxiosAdapter | undefined' is not assignable to type 'import("/home/mat/work/api-sig-elig/admin/node_modules/axios/index").AxiosAdapter | undefined'.
          Type 'import("/home/mat/work/api-sig-elig/admin/node_modules/openapi-client-axios/node_modules/axios/index").AxiosAdapter' is not assignable to type 'import("/home/mat/work/api-sig-elig/admin/node_modules/axios/index").AxiosAdapter'.
            Types of parameters 'config' and 'config' are incompatible.
              Type 'import("/home/mat/work/api-sig-elig/admin/node_modules/axios/index").AxiosRequestConfig' is not assignable to type 'import("/home/mat/work/api-sig-elig/admin/node_modules/openapi-client-axios/node_modules/axios/index").AxiosRequestConfig'.
                Types of property 'validateStatus' are incompatible.
                  Type '((status: number) => boolean) | null | undefined' is not assignable to type '((status: number) => boolean | null) | undefined'.
                    Type 'null' is not assignable to type '((status: number) => boolean | null) | undefined'.
    29 | 
    30 |     client.interceptors.request.use(
  > 31 |       (config: AxiosRequestConfig): AxiosRequestConfig => {
       |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    32 |         const token = JSON.parse(localStorage.getItem('token') ?? 'null');
    33 | 
    34 |         if (token) {

All that because VSCode added the import from axios and not from openapi-client-axios. Then I noticed that difference:

❯ diff -u node_modules/axios/index.d.ts node_modules/openapi-client-axios/node_modules/axios/index.d.ts
--- node_modules/axios/index.d.ts	1985-10-26 09:15:00.000000000 +0100
+++ node_modules/openapi-client-axios/node_modules/axios/index.d.ts	1985-10-26 09:15:00.000000000 +0100
@@ -59,10 +59,10 @@
   responseType?: ResponseType;
   xsrfCookieName?: string;
   xsrfHeaderName?: string;
-  onUploadProgress?: (progressEvent: any) => void;
-  onDownloadProgress?: (progressEvent: any) => void;
+  onUploadProgress?: (progressEvent: ProgressEvent) => void;
+  onDownloadProgress?: (progressEvent: ProgressEvent) => void;
   maxContentLength?: number;
-  validateStatus?: ((status: number) => boolean) | null;
+  validateStatus?: ((status: number) => boolean | null);
   maxBodyLength?: number;
   maxRedirects?: number;
   socketPath?: string | null;

I don't really understand why there is such a difference, but, well, it would be nice if the validateStatus signature was compatible.

Add support to select what server to use

At the moment the client is hard coded to use the first server in the definition regardless of how many are defined.

Sure it can be override by the axiosConfigDefaults.baseURL but then you have to manually find out the url or extract it from the document it would be much nicer to something like this

const api = new OpenAPIClientAxios({
  definition: 'https://example.com/api/openapi.json'
  server: 1
});

//or by method
api.selectServer(1);
//or by description
api.selectServer('Eu Server');

typegen does not follow referenced parameters

First of all, thank you for this project. Out of all the projects I have seen so far, this is the one that suites us best and we are currently trying to use it in our project.

My current problem is that typegen does not resolve $ref-objects that are parameters.

Example input:

openapi: "3.0.0"
info:
  title: ParamRefExample
  version: 1.0.0
paths:
  "/endpoint/{id}/one":
    get:
      operationId: operationOne
      parameters:
        - $ref: "#/components/parameters/Id"
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
  "/endpoint/{id}/two":
    get:
      operationId: operationTwo
      parameters:
        - $ref: "#/components/parameters/Id"
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Response'
components:
  parameters:
    Id:
      name: id
      required: true
      in: path
      schema:
        type: string
  schemas:
    Response:
      type: object
      properties:
        success:
          type: string

Notice the UnknownParamsObject in the the output of typegen.

import {
  OpenAPIClient,
  Parameters,
  UnknownParamsObject,
  OperationResponse,
  AxiosRequestConfig,
} from 'openapi-client-axios'; 

declare namespace Components {
  namespace Parameters {
    namespace Id {
      export type Id = string;
    }
  }
  namespace Schemas {
    export interface Response {
      success?: string;
    }
  }
}
declare namespace Paths {
  namespace OperationOne {
    namespace Responses {
      export type $200 = Components.Schemas.Response;
    }
  }
  namespace OperationTwo {
    namespace Responses {
      export type $200 = Components.Schemas.Response;
    }
  }
}

export interface OperationMethods {
  /**
   * operationOne
   */
  'operationOne'(
    parameters?: Parameters<UnknownParamsObject>,
    data?: any,
    config?: AxiosRequestConfig  
  ): OperationResponse<Paths.OperationOne.Responses.$200>
  /**
   * operationTwo
   */
  'operationTwo'(
    parameters?: Parameters<UnknownParamsObject>,
    data?: any,
    config?: AxiosRequestConfig  
  ): OperationResponse<Paths.OperationTwo.Responses.$200>
}

export interface PathsDictionary {
  ['/endpoint/{id}/one']: {
    /**
     * operationOne
     */
    'get'(
      parameters?: Parameters<UnknownParamsObject>,
      data?: any,
      config?: AxiosRequestConfig  
    ): OperationResponse<Paths.OperationOne.Responses.$200>
  }
  ['/endpoint/{id}/two']: {
    /**
     * operationTwo
     */
    'get'(
      parameters?: Parameters<UnknownParamsObject>,
      data?: any,
      config?: AxiosRequestConfig  
    ): OperationResponse<Paths.OperationTwo.Responses.$200>
  }
}

export type Client = OpenAPIClient<OperationMethods, PathsDictionary>

I guess I will look for a workaround in the short term, but it would be great if this was fixed.

Support user-configurable operation names

Hello!

Currently, the library relies solely on operationId to determine the function name that is attached to clients when they are created. This is certainly spec-compliant and will work for a majority of use-cases.

Unfortunately, I'm currently in the minority! 😁

I have an Express API I'm working on and I currently use a package which uses a few extended attributes to be able to perform automating wiring of the Express router as well as request/response validation. In this setup, my operationId are not unique. I have an open PR on this library to get us to the point where I may use operationId that look more like resource.verb (e.g. pets.list, pets.create, etc.) and not rely on the extended attributes.

Here, what if there were a new configuration option where an end-user could specify a pluggable strategy for determination of method names. This function, internally, would receive the current operation and would return a method name. This would allow me to map pets.create -> createPet (or whatever).

The library would ship a default configuration that matches the current operationId-based implementation.

I am more than happy to put together an initial implementation of this if you'd like to touch/feel it before further consideration. Just let me know!

Implementation details

We're basically looking to make https://github.com/anttiviljami/openapi-client-axios/blob/master/src/client.ts#L207 pluggable. So, at this point, the idea would be to call out to our "method name factory function" to determine the property that is assigned to the instance:

for (const operation of operations) {
  const { operationId } = operation;
  if (operationId) {
    instance[this.getMethodName(operation)] = this.createOperationMethod(operation);
  }
}

getMethodName would be responsible for considering the configured factory and resolving the method name. Configuration of the factory might look like:

// operationNameFactory probably has a better name
new OpenAPIClientAxios({ 
  definition: 'https://example.com/api/openapi.json',
  operationNameFactory: (operation) {
    // Representing the current implementation. Simply 
    // use the operationId as the method name.
    return operation.operationId
  }
});

Typegen: UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'replace' of undefined

Whenever I run typegen on my openapi yml file, I get the following error

typegen http://localhost:8080/openapi.yml
(node:21928) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'replace' of undefined
    at Object.normalizeTypeName (D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\node_modules\@anttiviljami\dtsgenerator\dist\core\typeNameConvertor.js:37:17)
    at generateMethodForOperation (D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:143:53)
    at D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:191:66
    at Array.map (<anonymous>)
    at generateOperationMethodTypings (D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:191:39)
    at D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:124:40
    at step (D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:52:23)
    at Object.next (D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:33:53)
    at fulfilled (D:\Programs\nvm\v14.12.0\node_modules\openapi-client-axios-typegen\typegen.js:24:58)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)

anttiviljami/dtsgenerator doesn't have issues open, and the original dtsgenerator doesn't have the file where the error occurs, so I figured it'd be best to post it here.

Edit: Realized I forgot to add operationId's, once I added them it solved the problem

TypeError: Expected `input` to be a `string`, got `undefined`

Hello

Im trying to use openapi-client-axios to generate a TS client, however, when I try either typegen http://localhost:8080/openapi > src/modules/client.d.ts or typegen /home/magick93/Downloads/openapi_vaults > src/modules/client.d.ts I get the below error.

OpenAPI definition

---
openapi: 3.0.1
info:
  title: Generated API
  version: "1.0"
paths:
  /vaults:
    get:
      responses:
        200:
          description: OK
          content:
            application/json: {}
  /vaults/vault:
    post:
      requestBody:
        content:
          application/json:
            schema:
              type: string
      responses:
        200:
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Namespace'
components:
  schemas:
    Namespace:
      type: object
      properties:
        apiVersion:
          type: string
        kind:
          type: string
        metadata:
          type: object
          properties:
            annotations:
              type: object
              additionalProperties:
                type: string
            clusterName:
              type: string
            creationTimestamp:
              type: string
            deletionGracePeriodSeconds:
              format: int64
              type: integer
            deletionTimestamp:
              type: string
            finalizers:
              type: array
              items:
                type: string
            generateName:
              type: string
            generation:
              format: int64
              type: integer
            initializers:
              type: object
              properties:
                pending:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                result:
                  type: object
                  properties:
                    apiVersion:
                      type: string
                    code:
                      format: int32
                      type: integer
                    details:
                      type: object
                      properties:
                        causes:
                          type: array
                          items:
                            type: object
                            properties:
                              field:
                                type: string
                              message:
                                type: string
                              reason:
                                type: string
                        group:
                          type: string
                        kind:
                          type: string
                        name:
                          type: string
                        retryAfterSeconds:
                          format: int32
                          type: integer
                        uid:
                          type: string
                    kind:
                      type: string
                    message:
                      type: string
                    metadata:
                      type: object
                      properties:
                        _continue:
                          type: string
                        resourceVersion:
                          type: string
                        selfLink:
                          type: string
                    reason:
                      type: string
                    status:
                      type: string
            labels:
              type: object
              additionalProperties:
                type: string
            name:
              type: string
            namespace:
              type: string
            ownerReferences:
              type: array
              items:
                type: object
                properties:
                  apiVersion:
                    type: string
                  blockOwnerDeletion:
                    type: boolean
                  controller:
                    type: boolean
                  kind:
                    type: string
                  name:
                    type: string
                  uid:
                    type: string
            resourceVersion:
              type: string
            selfLink:
              type: string
            uid:
              type: string
        spec:
          type: object
          properties:
            finalizers:
              type: array
              items:
                type: string
        status:
          type: object
          properties:
            phase:
              type: string

Error

typegen http://localhost:8080/openapi > src/modules/client.d.ts
(node:9561) UnhandledPromiseRejectionWarning: TypeError: Expected `input` to be a `string`, got `undefined`
    at Object.module.exports [as default] (/usr/lib/node_modules/openapi-client-axios-typegen/node_modules/indent-string/index.js:11:9)
    at /usr/lib/node_modules/openapi-client-axios-typegen/typegen.js:148:36
    at Array.map (<anonymous>)
    at generateOperationMethodTypings (/usr/lib/node_modules/openapi-client-axios-typegen/typegen.js:114:39)
    at /usr/lib/node_modules/openapi-client-axios-typegen/typegen.js:96:40
    at step (/usr/lib/node_modules/openapi-client-axios-typegen/typegen.js:32:23)
    at Object.next (/usr/lib/node_modules/openapi-client-axios-typegen/typegen.js:13:53)
    at fulfilled (/usr/lib/node_modules/openapi-client-axios-typegen/typegen.js:4:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:9561) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 4)
(node:9561) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

fail with installation of typegen: Can't install it

node@9db768f22148:/usr/src/app/ntp-dashboard$ yarn --version
1.22.4
node@9db768f22148:/usr/src/app/ntp-dashboard$ node --version
v13.12.0

node@9db768f22148:/usr/src/app/ntp-dashboard$ yarn add openapi-client-axios
yarn add v1.22.4
[1/4] Resolving packages...
[2/4] Fetching packages...
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[3/4] Linking dependencies...
warning " > [email protected]" has unmet peer dependency "webpack@^4.36.0 || ^5.0.0".
warning " > [email protected]" has unmet peer dependency "webpack@^4.0.0".
[4/4] Building fresh packages...
[-/4] ⢀ waiting...
[2/4] ⢀ ejs
[-/4] ⢀ waiting...
error /usr/src/app/ntp-dashboard/node_modules/openapi-client-axios: Command failed.
Exit code: 2
Command: npm run typegen:install
Arguments: 
Directory: /usr/src/app/ntp-dashboard/node_modules/openapi-client-axios
Output:
npm WARN lifecycle The node binary used for scripts is /tmp/yarn--1586597873701-0.30829400471264035/node but npm is using /usr/local/bin/node itself. Use the `--scripts-prepend-node-path` option to include the path for the node binary npm was executed with.

> [email protected] typegen:install /usr/src/app/ntp-dashboard/node_modules/openapi-client-axios
> cd typegen && npm install

sh: 1: cd: can't cd to typegen
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! [email protected] typegen:install: `cd typegen && npm install`
npm ERR! Exit status 2
npm ERR! 
npm ERR! Failed at the [email protected] typegen:install script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm WARN Local package.json exists, but node_modules missing, did you mean to install?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.