Skip to content

Commit

Permalink
Update LuneClient's template to populate response with metadata (#70)
Browse files Browse the repository at this point in the history
#67 introduces SuccessResponse<T>.

This change ensures the LuneClient template populates the data accordingly.
  • Loading branch information
rbruggem authored Jul 3, 2024
1 parent 5eea157 commit fbd93a6
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 39 deletions.
38 changes: 25 additions & 13 deletions src/templates/luneClient.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ import axios, { AxiosInstance, AxiosResponse, isAxiosError } from 'axios'
import camelCaseKeys from 'camelcase-keys'

import { ClientConfig } from './core/ClientConfig.js'
import {
ExtendedAxiosError,
ExtendedAxiosResponse,
extractRequestFromResponseInterceptor,
} from './core/SuccessResponse.js'
{{#each services}}
import { {{{name}}}Service } from './services/{{{name}}}Service.js';
{{/each}}
Expand Down Expand Up @@ -37,27 +42,34 @@ export class LuneClient {
this.client = axios.create()

// Convert to camelCase when receiving request
const camelCaseResponse = (response: AxiosResponse<unknown, unknown>) => ({
const camelCaseResponse = (response: AxiosResponse): ExtendedAxiosResponse => ({
...response,
_meta: {
...extractRequestFromResponseInterceptor(response),
response: response.data,
},
// SAFETY: The camelcase-keys type definitions are overly restrictive. The function
// handles all kinds of values just fine: arrays, numbers, strings, null etc.
//
// Instead of writing a bunch of type-detecting conditional code to satisfy the
// TS compiler let's just wholesale ignore this type mismatch – we don't know what
// value do we actually deal with here but the library will handle it.
data: camelCaseKeys(response.data as any, { deep: true }),
})
this.client.interceptors.response.use(camelCaseResponse, (error: unknown) => {
// There's a separate, slightly different callback for errors.
if (!isAxiosError(error)) {
throw error
}
if (error.response) {
error.response = camelCaseResponse(error.response)
}
// We need to return a rejected promise for it to work nice with axios.
return Promise.reject(error)
data: camelCaseKeys(response.data, { deep: true }),
})
this.client.interceptors.response.use(
camelCaseResponse,
(error: ExtendedAxiosError): Promise<ExtendedAxiosError> => {
// There's a separate, slightly different callback for errors.
if (!isAxiosError(error)) {
throw error
}
if (error.response) {
error.response = camelCaseResponse(error.response)
}
// We need to return a rejected promise for it to work nice with axios.
return Promise.reject(error)
},
)
}

public setAccount(accountId: string) {
Expand Down
76 changes: 50 additions & 26 deletions test/__snapshots__/index.spec.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,11 @@ exports[`v2 should generate: ./test/generated/v2/luneClient.ts 1`] = `
import camelCaseKeys from 'camelcase-keys'

import { ClientConfig } from './core/ClientConfig.js'
import {
ExtendedAxiosError,
ExtendedAxiosResponse,
extractRequestFromResponseInterceptor,
} from './core/SuccessResponse.js'
import { CollectionFormatService } from './services/CollectionFormatService.js';
import { ComplexService } from './services/ComplexService.js';
import { DefaultService } from './services/DefaultService.js';
Expand Down Expand Up @@ -763,27 +768,34 @@ export class LuneClient {
this.client = axios.create()

// Convert to camelCase when receiving request
const camelCaseResponse = (response: AxiosResponse<unknown, unknown>) => ({
const camelCaseResponse = (response: AxiosResponse): ExtendedAxiosResponse => ({
...response,
_meta: {
...extractRequestFromResponseInterceptor(response),
response: response.data,
},
// SAFETY: The camelcase-keys type definitions are overly restrictive. The function
// handles all kinds of values just fine: arrays, numbers, strings, null etc.
//
// Instead of writing a bunch of type-detecting conditional code to satisfy the
// TS compiler let's just wholesale ignore this type mismatch – we don't know what
// value do we actually deal with here but the library will handle it.
data: camelCaseKeys(response.data as any, { deep: true }),
})
this.client.interceptors.response.use(camelCaseResponse, (error: unknown) => {
// There's a separate, slightly different callback for errors.
if (!isAxiosError(error)) {
throw error
}
if (error.response) {
error.response = camelCaseResponse(error.response)
}
// We need to return a rejected promise for it to work nice with axios.
return Promise.reject(error)
data: camelCaseKeys(response.data, { deep: true }),
})
this.client.interceptors.response.use(
camelCaseResponse,
(error: ExtendedAxiosError): Promise<ExtendedAxiosError> => {
// There's a separate, slightly different callback for errors.
if (!isAxiosError(error)) {
throw error
}
if (error.response) {
error.response = camelCaseResponse(error.response)
}
// We need to return a rejected promise for it to work nice with axios.
return Promise.reject(error)
},
)
}

public setAccount(accountId: string) {
Expand Down Expand Up @@ -5304,6 +5316,11 @@ exports[`v3 should generate: ./test/generated/v3/luneClient.ts 1`] = `
import camelCaseKeys from 'camelcase-keys'

import { ClientConfig } from './core/ClientConfig.js'
import {
ExtendedAxiosError,
ExtendedAxiosResponse,
extractRequestFromResponseInterceptor,
} from './core/SuccessResponse.js'
import { CollectionFormatService } from './services/CollectionFormatService.js';
import { ComplexService } from './services/ComplexService.js';
import { DefaultService } from './services/DefaultService.js';
Expand Down Expand Up @@ -5357,27 +5374,34 @@ export class LuneClient {
this.client = axios.create()

// Convert to camelCase when receiving request
const camelCaseResponse = (response: AxiosResponse<unknown, unknown>) => ({
const camelCaseResponse = (response: AxiosResponse): ExtendedAxiosResponse => ({
...response,
_meta: {
...extractRequestFromResponseInterceptor(response),
response: response.data,
},
// SAFETY: The camelcase-keys type definitions are overly restrictive. The function
// handles all kinds of values just fine: arrays, numbers, strings, null etc.
//
// Instead of writing a bunch of type-detecting conditional code to satisfy the
// TS compiler let's just wholesale ignore this type mismatch – we don't know what
// value do we actually deal with here but the library will handle it.
data: camelCaseKeys(response.data as any, { deep: true }),
})
this.client.interceptors.response.use(camelCaseResponse, (error: unknown) => {
// There's a separate, slightly different callback for errors.
if (!isAxiosError(error)) {
throw error
}
if (error.response) {
error.response = camelCaseResponse(error.response)
}
// We need to return a rejected promise for it to work nice with axios.
return Promise.reject(error)
data: camelCaseKeys(response.data, { deep: true }),
})
this.client.interceptors.response.use(
camelCaseResponse,
(error: ExtendedAxiosError): Promise<ExtendedAxiosError> => {
// There's a separate, slightly different callback for errors.
if (!isAxiosError(error)) {
throw error
}
if (error.response) {
error.response = camelCaseResponse(error.response)
}
// We need to return a rejected promise for it to work nice with axios.
return Promise.reject(error)
},
)
}

public setAccount(accountId: string) {
Expand Down

0 comments on commit fbd93a6

Please sign in to comment.