Skip to content

Commit

Permalink
feat: expanded response to include other metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
ColinEberhardt committed Mar 8, 2023
1 parent 5d7501e commit 06a596c
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ const api = new ApiPet(config);
});

const pet = await api.getPetById(1);
console.log(pet.name);
console.log(pet.data.name);
})();
```

Expand Down
6 changes: 4 additions & 2 deletions features/support/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ export class ModelSteps extends BaseModelStep {
const configurationModule = require("../api/configuration.ts");
const mockTransport = async (params: RequestParameters) => {
this.requestParams = params;
return this.serverResponseObject;
return {
data: this.serverResponseObject
}
};

const config = new configurationModule.default(mockTransport);
Expand Down Expand Up @@ -127,7 +129,7 @@ export class ModelSteps extends BaseModelStep {

@then(/the response should be null/)
public checkResponseIsNull() {
assert.isNull(this.apiResponse);
assert.isNull(this.apiResponse.data);
}

@when(/calling the method ([a-zA-Z]*) and the server responds with/)
Expand Down
7 changes: 4 additions & 3 deletions template/api.ts.handlebars
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export default class Api{{_tag.name}} {
{{typeConvert schema ../../../_options}}
{{#if schema.default}} = {{{quoteIfString schema.default}}}{{/if}},
{{/each}}
): Promise<{{#if _response.schema}}HttpResponse<{{typeConvert _response.schema ../../_options}}>{{else}}null{{/if}}> {
): Promise<HttpResponse<{{#if _response.schema}}{{typeConvert _response.schema ../../_options}}{{else}}any{{/if}}>> {

const builder = new ParameterBuilder();
{{#each _sortedParameters}}{{#unless _optional}}
Expand All @@ -60,10 +60,11 @@ export default class Api{{_tag.name}} {
const response = await request(this.config, "{{@root.path}}", "{{@key}}", builder.parameters);
{{#if _response.schema}}
return {
data: deserialize(response, "{{typeConvert _response.schema}}")
... response,
data: deserialize(response.data, "{{typeConvert _response.schema}}")
};
{{else}}
return null;
return response;
{{/if}}
};
{{/ifEquals}}
Expand Down
9 changes: 5 additions & 4 deletions template/configuration.ts.handlebars
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { RequestParameters } from "./request";
import { HttpResponse } from "./response";

/**
* A function which performs a request to the API.
*/
export interface TransportFunc {
(request: RequestParameters): Promise<any>;
export interface Transport {
(request: RequestParameters): Promise<HttpResponse<any>>;
}

/**
Expand All @@ -29,9 +30,9 @@ export default class Configuration {
*/
public basePath?: string;
public bearerToken?: string;
public transport: TransportFunc;
public transport: Transport;

constructor(transport: TransportFunc) {
constructor(transport: Transport) {
this.transport = transport;
}
}
33 changes: 27 additions & 6 deletions template/fetch.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
import { RequestParameters } from "./request";
import { Transport } from "../api/configuration";

export default async function transport(params: RequestParameters) {
const response = await fetch(params.url, params);
if (response.status !== 200) {
throw new Error(`${response.status} ${response.statusText}`);
const parseHeaders = (headers: Headers) => {
let res: Record<string, string> = {};
for (let [key, value] of headers.entries()) {
res[key] = value;
}
return await response.json();
}
return res;
};

const transport: Transport = async function (params: RequestParameters) {
const fetchResponse = await fetch(params.url, params);

if (fetchResponse.ok) {
const json = await fetchResponse.json();
return {
data: json,
statusCode: fetchResponse.status,
headers: parseHeaders(fetchResponse.headers),
type: fetchResponse.type,
};
} else {
throw new Error(
`Error ${fetchResponse.status}: ${fetchResponse.statusText}`
);
}
};

export default transport;
9 changes: 4 additions & 5 deletions template/request.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,22 @@
import Configuration from "./configuration";
import { Parameter } from "./parameterBuilder";
import { HttpResponse } from "./response";

export interface Headers {
[index: string]: string;
}
type Headers = Record<string, string>;

export interface RequestParameters {
url: string;
method: string;
body?: string;
headers: Headers;
headers: Record<string, string>;
}

export async function request(
config: Configuration,
path: string,
method: string,
params: Parameter[]
): Promise<any> {
): Promise<HttpResponse<any>> {
// replace path parameters with values
for (const pathParam of params.filter((p) => p.location === "path")) {
path = path.replace(
Expand Down
5 changes: 4 additions & 1 deletion template/response.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,7 @@
*/
export interface HttpResponse<T> {
data: T;
}
statusCode: number;
headers: Record<string, string>;
type: string;
}
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"compilerOptions": {
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"target": "ES5",
"target": "ES6",
"noImplicitAny": true
}
}

0 comments on commit 06a596c

Please sign in to comment.