From 9759418ff89cf62f2ddd88236815aee702538552 Mon Sep 17 00:00:00 2001 From: Leslie Fung Date: Thu, 13 Dec 2018 11:09:41 +1100 Subject: [PATCH] Refactored axios client generation to expose a configurable class (#59) --- README.md | 18 +- clients/axios/client.spec.ts | 77 +- .../__snapshots__/axios-client.spec.ts.snap | 712 +++++++++--------- lib/src/generators/typescript/axios-client.ts | 86 ++- package.json | 2 +- 5 files changed, 496 insertions(+), 399 deletions(-) diff --git a/README.md b/README.md index 0b98dc907..a0dcc240d 100644 --- a/README.md +++ b/README.md @@ -60,11 +60,10 @@ This is work in progress as of 14 Nov 2018: [![License](https://img.shields.io/npm/l/@airtasker/spot.svg)](https://github.com/airtasker/spot/blob/master/package.json) - -- [Spot](#spot) -- [Usage](#usage) -- [Commands](#commands) - +* [Spot](#spot) +* [Usage](#usage) +* [Commands](#commands) + # Usage @@ -372,11 +371,10 @@ Define a default error for the endpoint. This can only be used once for an `@end # Commands - -- [`spot generate`](#spot-generate) -- [`spot help [COMMAND]`](#spot-help-command) -- [`spot init`](#spot-init) -- [`spot validate SPOT_CONTRACT`](#spot-validate-spot-contract) +* [`spot generate`](#spot-generate) +* [`spot help [COMMAND]`](#spot-help-command) +* [`spot init`](#spot-init) +* [`spot validate SPOT_CONTRACT`](#spot-validate-spot-contract) ## `spot generate` diff --git a/clients/axios/client.spec.ts b/clients/axios/client.spec.ts index 05b535b27..2cee0bad9 100644 --- a/clients/axios/client.spec.ts +++ b/clients/axios/client.spec.ts @@ -1,4 +1,4 @@ -import { createUser, deleteUser, findUsers, getUser } from "./sdk/client"; +import { SpotApi } from "./sdk/client"; import * as moxios from "moxios"; import { CreateUserResponse } from "./sdk/types"; @@ -7,6 +7,8 @@ const createUserResponse: CreateUserResponse = { created_at: "2018-01-01" }; +const configuredApi = new SpotApi({ baseUrl: "http://localhost:9999/api" }); + describe("TypeScript axios client sdk test", () => { beforeEach(() => { moxios.install(); @@ -23,10 +25,13 @@ describe("TypeScript axios client sdk test", () => { response: createUserResponse }); - await createUser({ name: "User 1", roles: "admin" }, "test-token"); + await configuredApi.createUser( + { name: "User 1", roles: "admin" }, + "test-token" + ); const request = moxios.requests.mostRecent(); - expect(request.config.url).toBe("/users/create"); + expect(request.config.url).toBe("http://localhost:9999/api/users/create"); }); it("passes the correct method and request body", async () => { @@ -35,7 +40,10 @@ describe("TypeScript axios client sdk test", () => { response: createUserResponse }); - await createUser({ name: "User 1", roles: "admin" }, "test-token"); + await configuredApi.createUser( + { name: "User 1", roles: "admin" }, + "test-token" + ); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("post"); @@ -51,7 +59,10 @@ describe("TypeScript axios client sdk test", () => { response: createUserResponse }); - await createUser({ name: "User 1", roles: "admin" }, "test-token"); + await configuredApi.createUser( + { name: "User 1", roles: "admin" }, + "test-token" + ); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("post"); @@ -64,7 +75,10 @@ describe("TypeScript axios client sdk test", () => { response: createUserResponse }); - await createUser({ name: "User 1", roles: "admin" }, undefined); + await configuredApi.createUser( + { name: "User 1", roles: "admin" }, + undefined + ); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("post"); expect(request.config.headers["Authorization"]).toBeUndefined(); @@ -76,7 +90,7 @@ describe("TypeScript axios client sdk test", () => { response: createUserResponse }); - const response = await createUser( + const response = await configuredApi.createUser( { name: "User 1", roles: "admin" }, "test-token" ); @@ -91,7 +105,10 @@ describe("TypeScript axios client sdk test", () => { }); try { - await createUser({ name: "User 1", roles: "admin" }, "test-token"); + await configuredApi.createUser( + { name: "User 1", roles: "admin" }, + "test-token" + ); } catch (e) { expect(e).toEqual( new Error("Invalid response for successful status code: {}") @@ -104,7 +121,7 @@ describe("TypeScript axios client sdk test", () => { status: 400 }); - const response = await createUser( + const response = await configuredApi.createUser( { name: "User 1", roles: "admin" }, "test-token" ); @@ -125,10 +142,10 @@ describe("TypeScript axios client sdk test", () => { ] }); - await findUsers(10, "user"); + await configuredApi.findUsers(10, "user"); const request = moxios.requests.mostRecent(); - expect(request.config.url).toBe("/users"); + expect(request.config.url).toBe("http://localhost:9999/api/users"); }); it("passes the correct method and queryParams", async () => { @@ -142,7 +159,7 @@ describe("TypeScript axios client sdk test", () => { ] }); - await findUsers(10, "user"); + await configuredApi.findUsers(10, "user"); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("get"); @@ -164,7 +181,7 @@ describe("TypeScript axios client sdk test", () => { ] }); - await findUsers(10, undefined); + await configuredApi.findUsers(10, undefined); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("get"); @@ -191,7 +208,7 @@ describe("TypeScript axios client sdk test", () => { response: expected }); - const response = await findUsers(10, "user"); + const response = await configuredApi.findUsers(10, "user"); expect(response.kind).toBe("success"); expect(response.data).toEqual(expected); }); @@ -211,7 +228,7 @@ describe("TypeScript axios client sdk test", () => { response: expected }); - const response = await findUsers(10, "user"); + const response = await configuredApi.findUsers(10, "user"); expect(response.kind).toBe("success"); expect(response.data).toEqual(expected); }); @@ -221,7 +238,7 @@ describe("TypeScript axios client sdk test", () => { status: 400 }); - const response = await findUsers(10, "user"); + const response = await configuredApi.findUsers(10, "user"); expect(response.kind).toBe("unknown-error"); expect(response.data).toBeUndefined(); }); @@ -237,11 +254,11 @@ describe("TypeScript axios client sdk test", () => { } }); - await getUser(123); + await configuredApi.getUser(123); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("get"); - expect(request.config.url).toBe("/users/123"); + expect(request.config.url).toBe("http://localhost:9999/api/users/123"); }); it("can handle successful request", async () => { @@ -254,7 +271,7 @@ describe("TypeScript axios client sdk test", () => { response: expected }); - const response = await getUser(123); + const response = await configuredApi.getUser(123); expect(response.kind).toBe("success"); expect(response.data).toEqual(expected); }); @@ -268,7 +285,7 @@ describe("TypeScript axios client sdk test", () => { response: expected }); - const response = await getUser(123); + const response = await configuredApi.getUser(123); expect(response.kind).toBe("success"); expect(response.data).toEqual(expected); }); @@ -285,7 +302,7 @@ describe("TypeScript axios client sdk test", () => { }); try { - await getUser(123); + await configuredApi.getUser(123); } catch (e) { expect(e).toEqual( new Error( @@ -304,7 +321,7 @@ describe("TypeScript axios client sdk test", () => { status: 400 }); - const response = await getUser(123); + const response = await configuredApi.getUser(123); expect(response.kind).toBe("unknown-error"); expect(response.data).toBeUndefined(); }); @@ -317,11 +334,13 @@ describe("TypeScript axios client sdk test", () => { response: null }); - await deleteUser(123, "test-token"); + await configuredApi.deleteUser(123, "test-token"); const request = moxios.requests.mostRecent(); expect(request.config.method).toBe("delete"); - expect(request.config.url).toBe("/users/123-confirmed"); + expect(request.config.url).toBe( + "http://localhost:9999/api/users/123-confirmed" + ); }); it("passes the correct header", async () => { @@ -330,7 +349,7 @@ describe("TypeScript axios client sdk test", () => { response: null }); - await deleteUser(123, "test-token"); + await configuredApi.deleteUser(123, "test-token"); const request = moxios.requests.mostRecent(); expect(request.config.headers["Authorization"]).toBe("test-token"); @@ -342,7 +361,7 @@ describe("TypeScript axios client sdk test", () => { response: null }); - const response = await deleteUser(123, "test-token"); + const response = await configuredApi.deleteUser(123, "test-token"); expect(response.kind).toBe("success"); expect(response.data).toEqual(null); }); @@ -354,7 +373,7 @@ describe("TypeScript axios client sdk test", () => { }); try { - await deleteUser(123, "test-token"); + await configuredApi.deleteUser(123, "test-token"); } catch (e) { expect(e).toEqual( new Error("Invalid response for successful status code: {}") @@ -372,7 +391,7 @@ describe("TypeScript axios client sdk test", () => { response: expected }); - const response = await deleteUser(123, "test-token"); + const response = await configuredApi.deleteUser(123, "test-token"); expect(response.kind).toBe("forbidden"); expect(response.data).toStrictEqual(expected); }); @@ -387,7 +406,7 @@ describe("TypeScript axios client sdk test", () => { }); try { - await deleteUser(123, "test-token"); + await configuredApi.deleteUser(123, "test-token"); } catch (e) { expect(e).toEqual( new Error( diff --git a/lib/src/generators/typescript/__snapshots__/axios-client.spec.ts.snap b/lib/src/generators/typescript/__snapshots__/axios-client.spec.ts.snap index d359fe4ec..4c571a3a7 100644 --- a/lib/src/generators/typescript/__snapshots__/axios-client.spec.ts.snap +++ b/lib/src/generators/typescript/__snapshots__/axios-client.spec.ts.snap @@ -7,194 +7,202 @@ import { CreateUserRequest, CreateUserResponse } from \\"./types\\"; import * as validators from \\"./validators\\"; -export async function createUser(request: CreateUserRequest, authToken: string | void): Promise<{ - kind: \\"success\\"; - data: CreateUserResponse; -} | { - kind: \\"unknown-error\\"; - data?: void; -}> { - if (!validators.validateCreateUser_request(request)) { - throw new Error(\`Invalid request: \${JSON.stringify(request, null, 2)}\`); - } - if (!validators.validateCreateUser_headerAuthToken(authToken)) { - throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); - } - const response = await axios({ - url: \\"/users/create\\", - method: \\"POST\\", - responseType: \\"json\\", - headers: { \\"Authorization\\": authToken }, - params: {}, - data: request, - validateStatus: () => true - }); - switch (response.status) { - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateCreateUser_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"success\\", - data: response.data - }; - } - else { - if (!validators.validateCreateUser_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"unknown-error\\", - data: response.data - }; - } - } +interface SpotApiConfig { + baseUrl: string; } -export async function deleteUser(userId: number, authToken: string): Promise<{ - kind: \\"success\\"; - data: null; -} | { - kind: \\"unknown-error\\"; - data: { - message: string; - }; -} | { - kind: \\"forbidden\\"; - data: { - message: string; - signedInAs: string; - }; -}> { - if (!validators.validateDeleteUser_paramUserId(userId)) { - throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); - } - if (!validators.validateDeleteUser_headerAuthToken(authToken)) { - throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); - } - const response = await axios({ - url: \\"/users/\\" + userId + \\"-confirmed\\", - method: \\"DELETE\\", - responseType: \\"json\\", - headers: { \\"Authorization\\": authToken }, - params: {}, - validateStatus: () => true - }); - switch (response.status) { - case 403: - if (!validators.validateDeleteUser_specificErrorForbidden(response.data)) { - throw new Error(\`Invalid response for status code 403: \${JSON.stringify(response.data, null, 2)}\`); +export class SpotApi { + constructor(private config: SpotApiConfig) { } + async createUser(request: CreateUserRequest, authToken: string | void): Promise<{ + kind: \\"success\\"; + data: CreateUserResponse; + } | { + kind: \\"unknown-error\\"; + data?: void; + }> { + if (!validators.validateCreateUser_request(request)) { + throw new Error(\`Invalid request: \${JSON.stringify(request, null, 2)}\`); + } + if (!validators.validateCreateUser_headerAuthToken(authToken)) { + throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); + } + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users/create\\", + method: \\"POST\\", + responseType: \\"json\\", + headers: { \\"Authorization\\": authToken }, + params: {}, + data: request, + validateStatus: () => true + }); + switch (response.status) { + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateCreateUser_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; } - return { - kind: \\"forbidden\\", - data: response.data - }; - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateDeleteUser_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + else { + if (!validators.validateCreateUser_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"success\\", - data: response.data - }; } - else { - if (!validators.validateDeleteUser_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + async deleteUser(userId: number, authToken: string): Promise<{ + kind: \\"success\\"; + data: null; + } | { + kind: \\"unknown-error\\"; + data: { + message: string; + }; + } | { + kind: \\"forbidden\\"; + data: { + message: string; + signedInAs: string; + }; + }> { + if (!validators.validateDeleteUser_paramUserId(userId)) { + throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); + } + if (!validators.validateDeleteUser_headerAuthToken(authToken)) { + throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); + } + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users/\\" + userId + \\"-confirmed\\", + method: \\"DELETE\\", + responseType: \\"json\\", + headers: { \\"Authorization\\": authToken }, + params: {}, + validateStatus: () => true + }); + switch (response.status) { + case 403: + if (!validators.validateDeleteUser_specificErrorForbidden(response.data)) { + throw new Error(\`Invalid response for status code 403: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"forbidden\\", + data: response.data + }; + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateDeleteUser_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; + } + else { + if (!validators.validateDeleteUser_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"unknown-error\\", - data: response.data - }; } } -} - -export async function findUsers(limit: number, search_term: string | void): Promise<{ - kind: \\"success\\"; - data: { - name: string; - age?: number; - }[]; -} | { - kind: \\"unknown-error\\"; - data?: void; -}> { - if (!validators.validateFindUsers_paramLimit(limit)) { - throw new Error(\`Invalid parameter limit: \${JSON.stringify(limit, null, 2)}\`); - } - if (!validators.validateFindUsers_paramSearch_term(search_term)) { - throw new Error(\`Invalid parameter search_term: \${JSON.stringify(search_term, null, 2)}\`); - } - const response = await axios({ - url: \\"/users\\", - method: \\"GET\\", - responseType: \\"json\\", - headers: {}, - params: { \\"limit\\": limit, \\"search_term\\": search_term }, - validateStatus: () => true - }); - switch (response.status) { - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateFindUsers_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"success\\", - data: response.data - }; + async findUsers(limit: number, search_term: string | void): Promise<{ + kind: \\"success\\"; + data: { + name: string; + age?: number; + }[]; + } | { + kind: \\"unknown-error\\"; + data?: void; + }> { + if (!validators.validateFindUsers_paramLimit(limit)) { + throw new Error(\`Invalid parameter limit: \${JSON.stringify(limit, null, 2)}\`); + } + if (!validators.validateFindUsers_paramSearch_term(search_term)) { + throw new Error(\`Invalid parameter search_term: \${JSON.stringify(search_term, null, 2)}\`); } - else { - if (!validators.validateFindUsers_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users\\", + method: \\"GET\\", + responseType: \\"json\\", + headers: {}, + params: { \\"limit\\": limit, \\"search_term\\": search_term }, + validateStatus: () => true + }); + switch (response.status) { + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateFindUsers_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; + } + else { + if (!validators.validateFindUsers_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"unknown-error\\", - data: response.data - }; } } -} - -export async function getUser(userId: number): Promise<{ - kind: \\"success\\"; - data: { - name: string; - age?: number; - }; -} | { - kind: \\"unknown-error\\"; - data?: void; -}> { - if (!validators.validateGetUser_paramUserId(userId)) { - throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); - } - const response = await axios({ - url: \\"/users/\\" + userId, - method: \\"GET\\", - responseType: \\"json\\", - headers: {}, - params: {}, - validateStatus: () => true - }); - switch (response.status) { - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateGetUser_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"success\\", - data: response.data - }; + async getUser(userId: number): Promise<{ + kind: \\"success\\"; + data: { + name: string; + age?: number; + }; + } | { + kind: \\"unknown-error\\"; + data?: void; + }> { + if (!validators.validateGetUser_paramUserId(userId)) { + throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); } - else { - if (!validators.validateGetUser_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users/\\" + userId, + method: \\"GET\\", + responseType: \\"json\\", + headers: {}, + params: {}, + validateStatus: () => true + }); + switch (response.status) { + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateGetUser_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; + } + else { + if (!validators.validateGetUser_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"unknown-error\\", - data: response.data - }; } } }" @@ -207,194 +215,202 @@ import { CreateUserRequest, CreateUserResponse } from \\"./types\\"; import * as validators from \\"./validators\\"; -export async function createUser(request: CreateUserRequest, authToken: string | void): Promise<{ - kind: \\"success\\"; - data: CreateUserResponse; -} | { - kind: \\"unknown-error\\"; - data?: void; -}> { - if (!validators.validateCreateUser_request(request)) { - throw new Error(\`Invalid request: \${JSON.stringify(request, null, 2)}\`); - } - if (!validators.validateCreateUser_headerAuthToken(authToken)) { - throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); - } - const response = await axios({ - url: \\"/users/create\\", - method: \\"POST\\", - responseType: \\"json\\", - headers: { \\"Authorization\\": authToken }, - params: {}, - data: request, - validateStatus: () => true - }); - switch (response.status) { - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateCreateUser_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"success\\", - data: response.data - }; - } - else { - if (!validators.validateCreateUser_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"unknown-error\\", - data: response.data - }; - } - } +interface SpotApiConfig { + baseUrl: string; } -export async function findUsers(limit: number, search_term: string | void): Promise<{ - kind: \\"success\\"; - data: { - name: string; - age?: number; - }[]; -} | { - kind: \\"unknown-error\\"; - data?: void; -}> { - if (!validators.validateFindUsers_paramLimit(limit)) { - throw new Error(\`Invalid parameter limit: \${JSON.stringify(limit, null, 2)}\`); - } - if (!validators.validateFindUsers_paramSearch_term(search_term)) { - throw new Error(\`Invalid parameter search_term: \${JSON.stringify(search_term, null, 2)}\`); - } - const response = await axios({ - url: \\"/users\\", - method: \\"GET\\", - responseType: \\"json\\", - headers: {}, - params: { \\"limit\\": limit, \\"search_term\\": search_term }, - validateStatus: () => true - }); - switch (response.status) { - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateFindUsers_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"success\\", - data: response.data - }; +export class SpotApi { + constructor(private config: SpotApiConfig) { } + async createUser(request: CreateUserRequest, authToken: string | void): Promise<{ + kind: \\"success\\"; + data: CreateUserResponse; + } | { + kind: \\"unknown-error\\"; + data?: void; + }> { + if (!validators.validateCreateUser_request(request)) { + throw new Error(\`Invalid request: \${JSON.stringify(request, null, 2)}\`); + } + if (!validators.validateCreateUser_headerAuthToken(authToken)) { + throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); } - else { - if (!validators.validateFindUsers_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users/create\\", + method: \\"POST\\", + responseType: \\"json\\", + headers: { \\"Authorization\\": authToken }, + params: {}, + data: request, + validateStatus: () => true + }); + switch (response.status) { + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateCreateUser_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; + } + else { + if (!validators.validateCreateUser_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"unknown-error\\", - data: response.data - }; } } -} - -export async function getUser(userId: number): Promise<{ - kind: \\"success\\"; - data: { - name: string; - age?: number; - }; -} | { - kind: \\"unknown-error\\"; - data?: void; -}> { - if (!validators.validateGetUser_paramUserId(userId)) { - throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); - } - const response = await axios({ - url: \\"/users/\\" + userId, - method: \\"GET\\", - responseType: \\"json\\", - headers: {}, - params: {}, - validateStatus: () => true - }); - switch (response.status) { - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateGetUser_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); - } - return { - kind: \\"success\\", - data: response.data - }; + async findUsers(limit: number, search_term: string | void): Promise<{ + kind: \\"success\\"; + data: { + name: string; + age?: number; + }[]; + } | { + kind: \\"unknown-error\\"; + data?: void; + }> { + if (!validators.validateFindUsers_paramLimit(limit)) { + throw new Error(\`Invalid parameter limit: \${JSON.stringify(limit, null, 2)}\`); } - else { - if (!validators.validateGetUser_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + if (!validators.validateFindUsers_paramSearch_term(search_term)) { + throw new Error(\`Invalid parameter search_term: \${JSON.stringify(search_term, null, 2)}\`); + } + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users\\", + method: \\"GET\\", + responseType: \\"json\\", + headers: {}, + params: { \\"limit\\": limit, \\"search_term\\": search_term }, + validateStatus: () => true + }); + switch (response.status) { + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateFindUsers_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; + } + else { + if (!validators.validateFindUsers_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"unknown-error\\", - data: response.data - }; } } -} - -export async function deleteUser(userId: number, authToken: string): Promise<{ - kind: \\"success\\"; - data: null; -} | { - kind: \\"unknown-error\\"; - data: { - message: string; - }; -} | { - kind: \\"forbidden\\"; - data: { - message: string; - signedInAs: string; - }; -}> { - if (!validators.validateDeleteUser_paramUserId(userId)) { - throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); - } - if (!validators.validateDeleteUser_headerAuthToken(authToken)) { - throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); - } - const response = await axios({ - url: \\"/users/\\" + userId + \\"-confirmed\\", - method: \\"DELETE\\", - responseType: \\"json\\", - headers: { \\"Authorization\\": authToken }, - params: {}, - validateStatus: () => true - }); - switch (response.status) { - case 403: - if (!validators.validateDeleteUser_specificErrorForbidden(response.data)) { - throw new Error(\`Invalid response for status code 403: \${JSON.stringify(response.data, null, 2)}\`); + async getUser(userId: number): Promise<{ + kind: \\"success\\"; + data: { + name: string; + age?: number; + }; + } | { + kind: \\"unknown-error\\"; + data?: void; + }> { + if (!validators.validateGetUser_paramUserId(userId)) { + throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); + } + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users/\\" + userId, + method: \\"GET\\", + responseType: \\"json\\", + headers: {}, + params: {}, + validateStatus: () => true + }); + switch (response.status) { + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateGetUser_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; } - return { - kind: \\"forbidden\\", - data: response.data - }; - default: if (response.status >= 200 && response.status < 300) { - if (!validators.validateDeleteUser_response(response.data)) { - throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + else { + if (!validators.validateGetUser_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"success\\", - data: response.data - }; } - else { - if (!validators.validateDeleteUser_genericError(response.data)) { - throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + async deleteUser(userId: number, authToken: string): Promise<{ + kind: \\"success\\"; + data: null; + } | { + kind: \\"unknown-error\\"; + data: { + message: string; + }; + } | { + kind: \\"forbidden\\"; + data: { + message: string; + signedInAs: string; + }; + }> { + if (!validators.validateDeleteUser_paramUserId(userId)) { + throw new Error(\`Invalid parameter userId: \${JSON.stringify(userId, null, 2)}\`); + } + if (!validators.validateDeleteUser_headerAuthToken(authToken)) { + throw new Error(\`Invalid parameter authToken: \${JSON.stringify(authToken, null, 2)}\`); + } + const response = await axios({ + baseURL: this.config.baseUrl, + url: \\"/users/\\" + userId + \\"-confirmed\\", + method: \\"DELETE\\", + responseType: \\"json\\", + headers: { \\"Authorization\\": authToken }, + params: {}, + validateStatus: () => true + }); + switch (response.status) { + case 403: + if (!validators.validateDeleteUser_specificErrorForbidden(response.data)) { + throw new Error(\`Invalid response for status code 403: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"forbidden\\", + data: response.data + }; + default: if (response.status >= 200 && response.status < 300) { + if (!validators.validateDeleteUser_response(response.data)) { + throw new Error(\`Invalid response for successful status code: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"success\\", + data: response.data + }; + } + else { + if (!validators.validateDeleteUser_genericError(response.data)) { + throw new Error(\`Invalid response for unknown error: \${JSON.stringify(response.data, null, 2)}\`); + } + return { + kind: \\"unknown-error\\", + data: response.data + }; } - return { - kind: \\"unknown-error\\", - data: response.data - }; } } }" diff --git a/lib/src/generators/typescript/axios-client.ts b/lib/src/generators/typescript/axios-client.ts index 2d7f436b8..e4c2533f9 100644 --- a/lib/src/generators/typescript/axios-client.ts +++ b/lib/src/generators/typescript/axios-client.ts @@ -22,6 +22,12 @@ import compact = require("lodash/compact"); const IMPORTED_AXIOS_NAME = "axios"; +const SPOT_API_CONFIG_INTERFACE = "SpotApiConfig"; +const SPOT_API_CONFIG = { + name: "config", + baseUrlProp: "baseUrl" +}; + export function generateAxiosClientSource(api: Api): string { const typeNames = Object.keys(api.types); return outputTypeScriptSource([ @@ -63,28 +69,78 @@ export function generateAxiosClientSource(api: Api): string { ), ts.createStringLiteral("./validators") ), - ...Object.entries(api.endpoints).map(([endpointName, endpoint]) => - generateEndpointFunction(api, endpointName, endpoint) - ) + generateSpotApiOptionsInterface(), + generateSpotApiClass(api) ]); } +function generateSpotApiOptionsInterface(): ts.InterfaceDeclaration { + return ts.createInterfaceDeclaration( + /*decorators*/ undefined, + /*modifiers*/ undefined, + SPOT_API_CONFIG_INTERFACE, + /*typeParameters*/ undefined, + /*heritageClauses*/ undefined, + [ + ts.createPropertySignature( + /*modifiers*/ undefined, + SPOT_API_CONFIG.baseUrlProp, + /*questionToken*/ undefined, + ts.createKeywordTypeNode(ts.SyntaxKind.StringKeyword), + /*initializer*/ undefined + ) + ] + ); +} + +function generateSpotApiClass(api: Api) { + return ts.createClassDeclaration( + /*decorators*/ undefined, + [ts.createModifier(ts.SyntaxKind.ExportKeyword)], + "SpotApi", + /*typeParameters*/ undefined, + /*heritageClause*/ undefined, + [ + ts.createConstructor( + /*decorators*/ undefined, + /*modifiers*/ undefined, + [ + ts.createParameter( + /*decorators*/ undefined, + [ts.createModifier(ts.SyntaxKind.PrivateKeyword)], + /*dotDotDotToken*/ undefined, + SPOT_API_CONFIG.name, + /*questionToken*/ undefined, + ts.createTypeReferenceNode( + SPOT_API_CONFIG_INTERFACE, + /*typeArguments*/ undefined + ) + ) + ], + ts.createBlock([]) + ), + ...Object.entries(api.endpoints).map(([endpointName, endpoint]) => + generateEndpointMethod(api, endpointName, endpoint) + ) + ] + ); +} + const REQUEST_PARAMETER = "request"; -function generateEndpointFunction( +function generateEndpointMethod( api: Api, endpointName: string, endpoint: Endpoint -): ts.FunctionDeclaration { +): ts.MethodDeclaration { const includeRequest = !isVoid(api, endpoint.requestType); - return ts.createFunctionDeclaration( + + return ts.createMethod( /*decorators*/ undefined, - [ - ts.createToken(ts.SyntaxKind.ExportKeyword), - ts.createToken(ts.SyntaxKind.AsyncKeyword) - ], - /*asteriskToken*/ undefined, + [ts.createToken(ts.SyntaxKind.AsyncKeyword)], + /*asterixToken*/ undefined, endpointName, + /*questionToken*/ undefined, /*typeParameters*/ undefined, [ ...(includeRequest @@ -267,6 +323,14 @@ function generateAxiosCall( [ ts.createObjectLiteral( [ + ts.createPropertyAssignment( + "baseURL", + ts.createIdentifier( + `this.${SPOT_API_CONFIG.name}.${ + SPOT_API_CONFIG.baseUrlProp + }` + ) + ), ts.createPropertyAssignment( "url", generatePath(endpoint.path) diff --git a/package.json b/package.json index f519361a6..142c90d88 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ "postpack": "rm -f oclif.manifest.json", "prepack": "rm -rf build; tsc -b --force && rm -rf build/examples && oclif-dev manifest && oclif-dev readme", "test": "jest --testPathIgnorePatterns '/node_modules/' --testPathIgnorePatterns '/clients'", - "axios:test": "yarn pack && ./bin/run generate --api examples/src/single-file/single-file-api.ts --generator axios-client -l typescript -o clients/axios/sdk && jest clients/axios", + "axios:test": "yarn pack && rm -rf ./clients/axios/sdk && ./bin/run generate --api examples/src/single-file/single-file-api.ts --generator axios-client -l typescript -o clients/axios/sdk && jest clients/axios", "prettier:list": "prettier --list-different \"**/*.js\" \"**/*.jsx\" \"**/*.ts\" \"**/*.tsx\"", "prettier:write": "prettier --write \"**/*.js\" \"**/*.jsx\" \"**/*.ts\" \"**/*.tsx\"", "release": "yarn version && oclif-dev readme && git add README.md && git commit README.md -m \"Update README\" && git push && npm publish --access=public"