openapistack / openapi-client-axios Goto Github PK
View Code? Open in Web Editor NEWJavaScript client library for consuming OpenAPI-enabled APIs with axios
Home Page: https://openapistack.co
License: MIT License
JavaScript client library for consuming OpenAPI-enabled APIs with axios
Home Page: https://openapistack.co
License: MIT License
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
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!
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
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"
.
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?
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
Is it possible integrate this client to the previous version swagger?
I need configure interceptors in order to check token for auth. How can I add this, and how can I set a default config fore every request?
Thx
Sometimes operationIds aren't very helpful, or completely missing.
Let's provide useful aliases for those cases. Some examples:
GET /pets
-> getPets
GET /pets/{id}
-> getPetsById
POST /pets
-> postPets
DELETE /pets/{id}
-> deletePetsById
Typegen output code breaks if an operationid contains a special character like .
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
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.
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.
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...
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.
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.
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
The below is a reproducible swagger file definitions.
We prepare 2 files.
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)
I observed some cases where typegen
runs successfully with references on some cases.
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.
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.
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?
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.
Please update package dtsgenerator.
You have 2.5.0 in typegen. Now is 3.10.0 available.
I need changes from horiuchi/dtsgenerator#472
Thanks a lot!
Hello, does the client handles type conversions like date-time?
endDate?: string; // date-time
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.
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!
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
Perhaps with something like this:
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.
Manually set headers overrides initial headers:
authorization: 'Bearer token'
Manually set headers are joined to initial headers:
authorization: 'initial header, Bearer token'
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'
}
}
);
Getting an "Unexpected token: punc (,)" error from UglifyJS when running build -- more specifically, to-parameter-pattern.js, line 14.
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": {...}
}
}
}
Is it possible to generate the client code offline, starting from the api json spec file?
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?
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
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
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!
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);
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?
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.
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~
Thanks for the great job.
Is integration possible with NUXT and in particular with auth_next? (@nuxtjs/auth-next, @nuxtjs/axios)
thank you
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.
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');
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.
Response of .post request is
config: {
...
url: '/product-manufacturer',
method: 'post',
data: '{"name":"aTest"}',
...
but request method is then method: 'GET',
Hello, the parameter value check in getRequestConfigForOperation fails for falsy values (e.g 0, false) and null.
Null values are allowed as per OpenAPI spec (https://swagger.io/docs/specification/data-models/data-types/#null).
In #5 the change was made to allow for all param types to be used in the first argument for an operation, when a operation has both query and path params the typegen only uses the PathParameters.
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
}
});
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
Swagger-Parser dependency has subdependency on openapi-schema-validation
Subdependency imports fs
, which prevents webpack from properly building for web
.
Is there an alternative package that it could be replaced by?
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: 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
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.
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?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.