mirror of
https://github.com/ferdikoomen/openapi-typescript-codegen.git
synced 2025-12-08 20:16:21 +00:00
Merge pull request #377 from nandorojo/async-token
Allow asynchronous bearer token
This commit is contained in:
commit
b79618fdb1
14
README.md
14
README.md
@ -339,6 +339,20 @@ import { OpenAPI } from './generated';
|
||||
OpenAPI.TOKEN = 'some-bearer-token';
|
||||
```
|
||||
|
||||
Alternatively, we also support an async method that provides the token for each request.
|
||||
You can simply assign this method to the same `TOKEN `property in the global OpenAPI object.
|
||||
|
||||
```typescript
|
||||
import { OpenAPI } from './generated';
|
||||
|
||||
const getToken = async () => {
|
||||
// Some code that requests a token...
|
||||
return 'SOME_TOKEN';
|
||||
}
|
||||
|
||||
OpenAPI.TOKEN = getToken;
|
||||
```
|
||||
|
||||
|
||||
### Compare to other generators
|
||||
Depending on which swagger generator you use, you will see different output.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "openapi-typescript-codegen",
|
||||
"version": "0.5.0",
|
||||
"version": "0.5.1",
|
||||
"description": "NodeJS library that generates Typescript or Javascript clients based on the OpenAPI specification.",
|
||||
"author": "Ferdi Koomen",
|
||||
"homepage": "https://github.com/ferdikoomen/openapi-typescript-codegen",
|
||||
|
||||
@ -4,7 +4,7 @@ interface Config {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
WITH_CREDENTIALS: boolean;
|
||||
TOKEN: string;
|
||||
TOKEN: string | (() => Promise<string>);
|
||||
}
|
||||
|
||||
export const OpenAPI: Config = {
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
function getHeaders(options: ApiRequestOptions): Headers {
|
||||
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
|
||||
const headers = new Headers({
|
||||
Accept: 'application/json',
|
||||
...options.headers,
|
||||
});
|
||||
|
||||
if (isDefined(OpenAPI.TOKEN) && OpenAPI.TOKEN !== '') {
|
||||
headers.append('Authorization', `Bearer ${OpenAPI.TOKEN}`);
|
||||
const token = await getToken();
|
||||
if (isDefined(token) && token !== '') {
|
||||
headers.append('Authorization', `Bearer ${token}`);
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
|
||||
@ -23,6 +23,9 @@ import { OpenAPI } from './OpenAPI';
|
||||
{{>functions/getFormData}}
|
||||
|
||||
|
||||
{{>functions/getToken}}
|
||||
|
||||
|
||||
{{>fetch/getHeaders}}
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
async function sendRequest(options: ApiRequestOptions, url: string): Promise<Response> {
|
||||
const request: RequestInit = {
|
||||
method: options.method,
|
||||
headers: getHeaders(options),
|
||||
headers: await getHeaders(options),
|
||||
body: getRequestBody(options),
|
||||
};
|
||||
return await fetch(url, request);
|
||||
|
||||
6
src/templates/core/functions/getToken.hbs
Normal file
6
src/templates/core/functions/getToken.hbs
Normal file
@ -0,0 +1,6 @@
|
||||
async function getToken(): Promise<string> {
|
||||
if (typeof OpenAPI.TOKEN === 'function') {
|
||||
return OpenAPI.TOKEN();
|
||||
}
|
||||
return OpenAPI.TOKEN;
|
||||
}
|
||||
@ -1,11 +1,12 @@
|
||||
function getHeaders(options: ApiRequestOptions): Headers {
|
||||
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
|
||||
const headers = new Headers({
|
||||
Accept: 'application/json',
|
||||
...options.headers,
|
||||
});
|
||||
|
||||
if (isDefined(OpenAPI.TOKEN) && OpenAPI.TOKEN !== '') {
|
||||
headers.append('Authorization', `Bearer ${OpenAPI.TOKEN}`);
|
||||
const token = await getToken();
|
||||
if (isDefined(token) && token !== '') {
|
||||
headers.append('Authorization', `Bearer ${token}`);
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
|
||||
@ -27,6 +27,9 @@ import { OpenAPI } from './OpenAPI';
|
||||
{{>functions/getFormData}}
|
||||
|
||||
|
||||
{{>functions/getToken}}
|
||||
|
||||
|
||||
{{>node/getHeaders}}
|
||||
|
||||
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
async function sendRequest(options: ApiRequestOptions, url: string): Promise<Response> {
|
||||
const request: RequestInit = {
|
||||
method: options.method,
|
||||
headers: getHeaders(options),
|
||||
headers: await getHeaders(options),
|
||||
body: getRequestBody(options),
|
||||
};
|
||||
return await fetch(url, request);
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
function getHeaders(options: ApiRequestOptions): Headers {
|
||||
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
|
||||
const headers = new Headers({
|
||||
Accept: 'application/json',
|
||||
...options.headers,
|
||||
});
|
||||
|
||||
if (isDefined(OpenAPI.TOKEN) && OpenAPI.TOKEN !== '') {
|
||||
headers.append('Authorization', `Bearer ${OpenAPI.TOKEN}`);
|
||||
const token = await getToken();
|
||||
if (isDefined(token) && token !== '') {
|
||||
headers.append('Authorization', `Bearer ${token}`);
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
|
||||
@ -26,6 +26,9 @@ import { OpenAPI } from './OpenAPI';
|
||||
{{>functions/getFormData}}
|
||||
|
||||
|
||||
{{>functions/getToken}}
|
||||
|
||||
|
||||
{{>fetch/getHeaders}}
|
||||
|
||||
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
function sendRequest(options: ApiRequestOptions, url: string): Promise<XMLHttpRequest> {
|
||||
async function sendRequest(options: ApiRequestOptions, url: string): Promise<XMLHttpRequest> {
|
||||
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(options.method, url, true);
|
||||
xhr.withCredentials = OpenAPI.WITH_CREDENTIALS;
|
||||
|
||||
const headers = await getHeaders(options);
|
||||
headers.forEach((value: string, key: string) => {
|
||||
xhr.setRequestHeader(key, value);
|
||||
});
|
||||
|
||||
return new Promise<XMLHttpRequest>((resolve, reject) => {
|
||||
try {
|
||||
const xhr = new XMLHttpRequest();
|
||||
xhr.open(options.method, url, true);
|
||||
xhr.withCredentials = OpenAPI.WITH_CREDENTIALS;
|
||||
|
||||
const headers = getHeaders(options);
|
||||
headers.forEach((value: string, key: string) => {
|
||||
xhr.setRequestHeader(key, value);
|
||||
});
|
||||
|
||||
xhr.onreadystatechange = () => {
|
||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
||||
resolve(xhr);
|
||||
}
|
||||
};
|
||||
|
||||
xhr.send(getRequestBody(options));
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
|
||||
@ -12,6 +12,7 @@ import fetchSendRequest from '../templates/core/fetch/sendRequest.hbs';
|
||||
import functionCatchErrors from '../templates/core/functions/catchErrors.hbs';
|
||||
import functionGetFormData from '../templates/core/functions/getFormData.hbs';
|
||||
import functionGetQueryString from '../templates/core/functions/getQueryString.hbs';
|
||||
import functionGetToken from '../templates/core/functions/getToken.hbs';
|
||||
import functionGetUrl from '../templates/core/functions/getUrl.hbs';
|
||||
import functionIsBinary from '../templates/core/functions/isBinary.hbs';
|
||||
import functionIsBlob from '../templates/core/functions/isBlob.hbs';
|
||||
@ -131,6 +132,7 @@ export function registerHandlebarTemplates(): Templates {
|
||||
// Generic functions used in 'request' file @see src/templates/core/request.hbs for more info
|
||||
Handlebars.registerPartial('functions/catchErrors', Handlebars.template(functionCatchErrors));
|
||||
Handlebars.registerPartial('functions/getFormData', Handlebars.template(functionGetFormData));
|
||||
Handlebars.registerPartial('functions/getToken', Handlebars.template(functionGetToken));
|
||||
Handlebars.registerPartial('functions/getQueryString', Handlebars.template(functionGetQueryString));
|
||||
Handlebars.registerPartial('functions/getUrl', Handlebars.template(functionGetUrl));
|
||||
Handlebars.registerPartial('functions/isBinary', Handlebars.template(functionIsBinary));
|
||||
|
||||
@ -61,7 +61,7 @@ interface Config {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
WITH_CREDENTIALS: boolean;
|
||||
TOKEN: string;
|
||||
TOKEN: string | (() => Promise<string>);
|
||||
}
|
||||
|
||||
export const OpenAPI: Config = {
|
||||
@ -134,14 +134,22 @@ function getFormData(params: Record<string, any>): FormData {
|
||||
return formData;
|
||||
}
|
||||
|
||||
function getHeaders(options: ApiRequestOptions): Headers {
|
||||
async function getToken(): Promise<string> {
|
||||
if (typeof OpenAPI.TOKEN === 'function') {
|
||||
return OpenAPI.TOKEN();
|
||||
}
|
||||
return OpenAPI.TOKEN;
|
||||
}
|
||||
|
||||
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
|
||||
const headers = new Headers({
|
||||
Accept: 'application/json',
|
||||
...options.headers,
|
||||
});
|
||||
|
||||
if (isDefined(OpenAPI.TOKEN) && OpenAPI.TOKEN !== '') {
|
||||
headers.append('Authorization', \`Bearer \${OpenAPI.TOKEN}\`);
|
||||
const token = await getToken();
|
||||
if (isDefined(token) && token !== '') {
|
||||
headers.append('Authorization', \`Bearer \${token}\`);
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
@ -173,7 +181,7 @@ function getRequestBody(options: ApiRequestOptions): BodyInit | undefined {
|
||||
async function sendRequest(options: ApiRequestOptions, url: string): Promise<Response> {
|
||||
const request: RequestInit = {
|
||||
method: options.method,
|
||||
headers: getHeaders(options),
|
||||
headers: await getHeaders(options),
|
||||
body: getRequestBody(options),
|
||||
};
|
||||
return await fetch(url, request);
|
||||
@ -2096,7 +2104,7 @@ interface Config {
|
||||
BASE: string;
|
||||
VERSION: string;
|
||||
WITH_CREDENTIALS: boolean;
|
||||
TOKEN: string;
|
||||
TOKEN: string | (() => Promise<string>);
|
||||
}
|
||||
|
||||
export const OpenAPI: Config = {
|
||||
@ -2169,14 +2177,22 @@ function getFormData(params: Record<string, any>): FormData {
|
||||
return formData;
|
||||
}
|
||||
|
||||
function getHeaders(options: ApiRequestOptions): Headers {
|
||||
async function getToken(): Promise<string> {
|
||||
if (typeof OpenAPI.TOKEN === 'function') {
|
||||
return OpenAPI.TOKEN();
|
||||
}
|
||||
return OpenAPI.TOKEN;
|
||||
}
|
||||
|
||||
async function getHeaders(options: ApiRequestOptions): Promise<Headers> {
|
||||
const headers = new Headers({
|
||||
Accept: 'application/json',
|
||||
...options.headers,
|
||||
});
|
||||
|
||||
if (isDefined(OpenAPI.TOKEN) && OpenAPI.TOKEN !== '') {
|
||||
headers.append('Authorization', \`Bearer \${OpenAPI.TOKEN}\`);
|
||||
const token = await getToken();
|
||||
if (isDefined(token) && token !== '') {
|
||||
headers.append('Authorization', \`Bearer \${token}\`);
|
||||
}
|
||||
|
||||
if (options.body) {
|
||||
@ -2208,7 +2224,7 @@ function getRequestBody(options: ApiRequestOptions): BodyInit | undefined {
|
||||
async function sendRequest(options: ApiRequestOptions, url: string): Promise<Response> {
|
||||
const request: RequestInit = {
|
||||
method: options.method,
|
||||
headers: getHeaders(options),
|
||||
headers: await getHeaders(options),
|
||||
body: getRequestBody(options),
|
||||
};
|
||||
return await fetch(url, request);
|
||||
|
||||
@ -27,8 +27,8 @@ async function stop() {
|
||||
await browser.close();
|
||||
}
|
||||
|
||||
async function evaluate(fn) {
|
||||
return await page.evaluate(fn);
|
||||
async function evaluate(fn, ...args) {
|
||||
return await page.evaluate(fn, args);
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
@ -21,6 +21,18 @@ describe('v2.fetch', () => {
|
||||
await browser.stop();
|
||||
});
|
||||
|
||||
it('requests token', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
window.api.OpenAPI.TOKEN = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve('MY_TOKEN');
|
||||
}, 500);
|
||||
});
|
||||
return await window.api.SimpleService.getCallWithoutParametersAndResponse();
|
||||
});
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
return await window.api.ComplexService.complexTypes({
|
||||
|
||||
@ -21,6 +21,18 @@ describe('v2.fetch', () => {
|
||||
await browser.stop();
|
||||
});
|
||||
|
||||
it('requests token', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
window.api.OpenAPI.TOKEN = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve('MY_TOKEN');
|
||||
}, 500);
|
||||
});
|
||||
return await window.api.SimpleService.getCallWithoutParametersAndResponse();
|
||||
});
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
return await window.api.ComplexService.complexTypes({
|
||||
|
||||
@ -17,8 +17,17 @@ describe('v2.node', () => {
|
||||
await server.stop();
|
||||
});
|
||||
|
||||
it('requests token', async () => {
|
||||
const { OpenAPI, SimpleService } = require('./generated/v2/node/index.js');
|
||||
const tokenRequest = jest.fn().mockResolvedValue('MY_TOKEN')
|
||||
OpenAPI.TOKEN = tokenRequest;
|
||||
const result = await SimpleService.getCallWithoutParametersAndResponse();
|
||||
expect(tokenRequest.mock.calls.length).toBe(1);
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
const {ComplexService} = require('./generated/v2/node/index.js');
|
||||
const { ComplexService } = require('./generated/v2/node/index.js');
|
||||
const result = await ComplexService.complexTypes({
|
||||
first: {
|
||||
second: {
|
||||
|
||||
@ -21,6 +21,18 @@ describe('v2.xhr', () => {
|
||||
await browser.stop();
|
||||
});
|
||||
|
||||
it('requests token', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
window.api.OpenAPI.TOKEN = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve('MY_TOKEN');
|
||||
}, 500);
|
||||
});
|
||||
return await window.api.SimpleService.getCallWithoutParametersAndResponse();
|
||||
});
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
return await window.api.ComplexService.complexTypes({
|
||||
|
||||
@ -21,8 +21,16 @@ describe('v3.fetch', () => {
|
||||
await browser.stop();
|
||||
});
|
||||
|
||||
it('runs', async () => {
|
||||
expect(true).toBeTruthy();
|
||||
it('requests token', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
window.api.OpenAPI.TOKEN = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve('MY_TOKEN');
|
||||
}, 500);
|
||||
});
|
||||
return await window.api.SimpleService.getCallWithoutParametersAndResponse();
|
||||
});
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
|
||||
@ -21,8 +21,16 @@ describe('v3.fetch', () => {
|
||||
await browser.stop();
|
||||
});
|
||||
|
||||
it('runs', async () => {
|
||||
expect(true).toBeTruthy();
|
||||
it('requests token', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
window.api.OpenAPI.TOKEN = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve('MY_TOKEN');
|
||||
}, 500);
|
||||
});
|
||||
return await window.api.SimpleService.getCallWithoutParametersAndResponse();
|
||||
});
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
|
||||
@ -17,8 +17,17 @@ describe('v3.node', () => {
|
||||
await server.stop();
|
||||
});
|
||||
|
||||
it('requests token', async () => {
|
||||
const { OpenAPI, SimpleService } = require('./generated/v2/node/index.js');
|
||||
const tokenRequest = jest.fn().mockResolvedValue('MY_TOKEN')
|
||||
OpenAPI.TOKEN = tokenRequest;
|
||||
const result = await SimpleService.getCallWithoutParametersAndResponse();
|
||||
expect(tokenRequest.mock.calls.length).toBe(1);
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
const {ComplexService} = require('./generated/v3/node/index.js');
|
||||
const { ComplexService } = require('./generated/v3/node/index.js');
|
||||
const result = await ComplexService.complexTypes({
|
||||
first: {
|
||||
second: {
|
||||
|
||||
@ -21,6 +21,18 @@ describe('v3.xhr', () => {
|
||||
await browser.stop();
|
||||
});
|
||||
|
||||
it('requests token', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
window.api.OpenAPI.TOKEN = new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve('MY_TOKEN');
|
||||
}, 500);
|
||||
});
|
||||
return await window.api.SimpleService.getCallWithoutParametersAndResponse();
|
||||
});
|
||||
expect(result.headers.authorization).toBe('Bearer MY_TOKEN');
|
||||
});
|
||||
|
||||
it('complexService', async () => {
|
||||
const result = await browser.evaluate(async () => {
|
||||
return await window.api.ComplexService.complexTypes({
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user