Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/nfroidure/openapi-ts-sdk-builder
Create a TypeScript SDK from an OpenAPI 3 definition
https://github.com/nfroidure/openapi-ts-sdk-builder
hacktoberfest openapi sdk-builder
Last synced: 25 days ago
JSON representation
Create a TypeScript SDK from an OpenAPI 3 definition
- Host: GitHub
- URL: https://github.com/nfroidure/openapi-ts-sdk-builder
- Owner: nfroidure
- License: mit
- Created: 2020-09-04T07:26:46.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2024-10-03T07:50:30.000Z (about 1 month ago)
- Last Synced: 2024-10-10T20:34:35.848Z (about 1 month ago)
- Topics: hacktoberfest, openapi, sdk-builder
- Language: TypeScript
- Homepage:
- Size: 1.03 MB
- Stars: 10
- Watchers: 3
- Forks: 2
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING
- Funding: .github/FUNDING.yml
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
[//]: # ( )
[//]: # (This file is automatically generated by a `metapak`)
[//]: # (module. Do not change it except between the)
[//]: # (`content:start/end` flags, your changes would)
[//]: # (be overridden.)
[//]: # ( )
# openapi-ts-sdk-builder
> Create a TypeScript SDK from an OpenAPI 3 definition[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/nfroidure/openapi-ts-sdk-builder/blob/main/LICENSE)
[//]: # (::contents:start)
A TypeScript rewrite of
[openapi-js-sdk-builder](https://github.com/sencrop/openapi-js-sdk-builder).It basically brings a minimal TypeScript SDK from an OpenAPI3 file with no OOP
inside. It works with any HTTP client.# Usage
With a raw Node script:
```js
import { generateSDKFromOpenAPI } from 'openapi-ts-sdk-builder';
import { readFileSync, writeFileSync } from 'fs';const openAPIContents = readFileSync('openapi.json', 'utf-8');
const sdkContents = generateSDKFromOpenAPI(
openAPIContents,
{
sdkVersion: 'v1.1.1',
ignoredParametersNames: ['cookie', 'X-API-Version', 'X-SDK-Version'],
undocumentedParametersNames: ['X-Application-Version'],
},
{
generateUnusedSchemas: true,
brandedTypes: [
'SensorUUID',
'UUID',
'Locale',
'TimeZone',
'ValueName',
'SensorVariable',
],
generateRealEnums: true,
exportNamespaces: true,
},
);writeFileSync('src/sdk.ts', sdkContents, 'utf-8');
```Sample usage with `axios`:
```ts
import BaseAPI, { APIStatuses } from './sdk.ts';
import axios from 'axios';
import querystring from 'querystring';
import type { RequestExecutor } from './sdk.ts';
import type { AxiosRequestConfig } from 'axios';const executeRequest: RequestExecutor = async (
httpRequest,
operationId,
options,
) => {
const callOptions = {
...options,
baseURL: 'http://localhost:3000',
url: httpRequest.path,
method: httpRequest.method,
headers: {
...(options.headers || {}),
...(httpRequest.headers || {}),
},
params: httpRequest.params,
data: httpRequest.body,
paramsSerializer: querystring.stringify.bind(querystring),
validateStatus: (status: number) =>
APIStatuses[operationId].includes(status),
};
const response = await axios(callOptions);return {
status: response.status,
headers: response.headers,
body: response.data,
};
};// Use the API
await BaseAPI.getPing(executeRequest);
await BaseAPI.getUser(executeRequest, { userId: '123' });// Generate URIs only use the API then
await APIURIBuilders.buildGetPingURI({
/*...*/
});// To know which method is used by an endpoint
APIMethods.getPing; // => get// To know which status codes can be returned by an endpoint
APIStatuses.getPing; // => ["default", 200]// Generate a complete endpoint input
// (may be useful when you want to pass
// HTTP requests to another process )
APIInputBuilders.buildGetPingInput({
/*...*/
});
```You can also safely operate on the API by doing so:
```ts
import BaseAPI, { APIStatuses } from './sdk.ts';
import config from './config';
import YError from 'yerror';
import type { RequestExecutor, Components } from './sdk.ts';
import type { AxiosRequestConfig } from 'axios';export { Enums };
export type { Components };type AuthTokenInput = { token?: string };
const API = Object.keys(BaseAPI).reduce((FinalAPI, operationId) => {
FinalAPI[operationId] = async (
{ token, ...input }: unknown & AuthTokenInput,
options: AxiosRequestConfig = {},
) => {
try {
const response = await BaseAPI[operationId](
executeRequest,
{
...input,
xApplicationVersion: config.applicationVersion,
},
{
...options,
baseURL: config.apiURL,
headers: {
...options.headers,
...(token
? {
authorization: `Bearer ${token}`,
}
: {}),
},
},
);
return response;
} catch (err) {
console.error('Got an API error:', err.stack);
throw new YError(
err.response?.data?.error ? 'E_API_ERROR' : 'E_UNEXPECTED_ERROR',
err.response?.data,
);
}
};
return FinalAPI;
}, {}) as {
[P in keyof typeof BaseAPI]: (
input: Parameters[1] & AuthTokenInput,
config?: AxiosRequestConfig,
) => Promise>;
};export default API;
```Finally, you may appreciate using it with the
[`useSSR` React hook](https://github.com/vercel/swr) to benefit from your SDK
types:```ts
import useSWR from 'swr';
import API from './api';type Handler = (input: I) => Promise;
type HandlerInput = T extends Handler ? I : never;
type HandlerOutput = T extends Handler ? I : never;const API_KEYS: Record = Object.keys(API).reduce((hash, key) => {
hash[API[key]] = key;
return hash;
}, {});export default function useAPISWR>(
swrCouple: [T, HandlerInput],
options?: Parameters[2],
) {
const uniqueKey = swrCouple
? Object.keys(swrCouple[1]).reduce(
(finalKey, key) => finalKey + key + JSON.stringify(swrCouple[1][key]),
// Sadly, here, we cannot rely on `swrCouple[0].name` to
// build the unicity key since the build destroys it
API_KEYS[swrCouple[0]] + '-',
)
: null;return useSWR<
Awaited> extends { body: infer D } ? D : never
>(
uniqueKey,
async () => (await swrCouple[0](swrCouple[1])).body,
options as any,
);
}
```[//]: # (::contents:end)
### openapi-ts-sdk-builder~generateSDKFromOpenAPI(openAPIContent, options, [typeOptions]) ⇒
Promise.<string>
Build a JS SDK from an OpenAPI file**Kind**: inner method of [
openapi-ts-sdk-builder
](#module_openapi-ts-sdk-builder)
**Returns**:Promise.<string>
- The SDK JS code| Param | Type | Description |
| --- | --- | --- |
| openAPIContent |string
| |
| options |Object
| |
| options.sdkVersion |string
| The SDK version |
| [options.sdkName] |string
| The SDK name (default to API) |
| [options.ignoredParametersNames] |Array.<string>
| Provide a list of parameters to ignore |
| [options.undocumentedParametersNames] |Array.<string>
| Provide a list of parameters to keep undocumented |
| [typeOptions] |Object
| Options to be passed to the type generator |# Authors
- [Nicolas Froidure](https://insertafter.com/en/index.html)# License
[MIT](https://github.com/nfroidure/openapi-ts-sdk-builder/blob/main/LICENSE)