axios-rest-resource
Advanced tools
Comparing version 0.5.0 to 0.6.0-rc.0
@@ -1,15 +0,24 @@ | ||
import { AxiosInstance, AxiosPromise, AxiosRequestConfig } from 'axios'; | ||
export declare type IAPIMethod = (requestConfig?: Partial<AxiosRequestConfig>) => AxiosPromise; | ||
export declare type IResource<Methods extends string> = { | ||
[Method in Methods]: IAPIMethod; | ||
}; | ||
declare type RequestMethod = 'get' | 'delete' | 'head' | 'options' | 'post' | 'put' | 'patch'; | ||
export interface IAPIMethodSchema { | ||
import { AxiosInstance, AxiosPromise, AxiosRequestConfig, AxiosResponse } from 'axios'; | ||
export declare type RequestMethod = 'get' | 'delete' | 'head' | 'options' | 'post' | 'put' | 'patch'; | ||
interface IAPIMethodSchemaBase { | ||
method: RequestMethod; | ||
url?: string; | ||
} | ||
export declare type IResourceSchema<T extends string> = { | ||
[Key in T]: IAPIMethodSchema; | ||
export interface IAPIMethodSchema<TParams extends any[] = any[], TResponse = any> extends IAPIMethodSchemaBase { | ||
transformRequest?: (...args: TParams) => AxiosRequestConfig; | ||
transformResponse?: (response: AxiosResponse) => TResponse; | ||
} | ||
declare type TransformedRequestMethod<TParams extends any[]> = (...args: TParams) => AxiosPromise; | ||
declare type TransformedResponseMethod<TResponse> = (config?: AxiosRequestConfig) => Promise<TResponse>; | ||
declare type FullyTransformedMethod<TParams extends any[], TResponse> = (...args: TParams) => Promise<TResponse>; | ||
declare type WithBothTransforms<TParams extends any[], TResponse> = FullyTransformedMethod<TParams, TResponse>; | ||
declare type WithRequestTransform<TParams extends any[]> = TransformedRequestMethod<TParams>; | ||
declare type WithResponseTransform<TResponse> = TransformedResponseMethod<TResponse>; | ||
declare type WithNoTransforms = (config?: AxiosRequestConfig) => AxiosPromise; | ||
export declare type IAPIMethod<Schema> = Schema extends IAPIMethodSchema<infer TParams, infer TResponse> ? Schema['transformRequest'] extends (...args: any[]) => any ? Schema['transformResponse'] extends (response: AxiosResponse) => any ? WithBothTransforms<TParams, TResponse> : WithRequestTransform<TParams> : Schema['transformResponse'] extends (response: AxiosResponse) => any ? WithResponseTransform<TResponse> : WithNoTransforms : never; | ||
export declare type IResource<Schema> = { | ||
[K in keyof Schema]: IAPIMethod<Schema[K]>; | ||
}; | ||
export declare type IResourceMethodsDefault = 'create' | 'read' | 'readOne' | 'remove' | 'update'; | ||
export declare type IResourceSchema<T extends string> = Record<T, IAPIMethodSchema>; | ||
interface IAxiosConfig extends AxiosRequestConfig { | ||
@@ -22,6 +31,6 @@ baseURL: string; | ||
constructor(axiosConfig: IAxiosConfig); | ||
build(resourceUrl: string): IResource<IResourceMethodsDefault>; | ||
build<Methods extends string>(resourceUrl: string, schema: IResourceSchema<Methods>): IResource<Methods>; | ||
protected _build<Methods extends string>(resourceUrl: string, schema: IResourceSchema<Methods>): IResource<Methods>; | ||
build(resourceUrl: string): IResource<IResourceSchema<IResourceMethodsDefault>>; | ||
build<T extends Record<string, IAPIMethodSchema>>(resourceUrl: string, schema: T): IResource<T>; | ||
protected _build<T extends Record<string, IAPIMethodSchema>>(resourceUrl: string, schema: T): IResource<T>; | ||
} | ||
export {}; |
@@ -43,6 +43,42 @@ "use strict"; | ||
url = "".concat(resourceUrl).concat(url); | ||
resource[methodName] = function (requestConfig) { | ||
if (requestConfig === void 0) { requestConfig = {}; } | ||
return _this.axiosInstance.request(__assign(__assign(__assign({}, requestConfig), methodSchema), { url: url })); | ||
var makeRequest = function (config) { | ||
if (config === void 0) { config = {}; } | ||
var requestConfig = __assign(__assign({}, config), { method: methodSchema.method, url: url }); | ||
if (requestConfig.data) { | ||
requestConfig.transformRequest = [function (data) { return data; }]; | ||
} | ||
return _this.axiosInstance.request(requestConfig); | ||
}; | ||
if (methodSchema.transformRequest && methodSchema.transformResponse) { | ||
var method = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var transformedConfig = methodSchema.transformRequest.apply(methodSchema, args); | ||
return makeRequest(transformedConfig).then(methodSchema.transformResponse); | ||
}; | ||
resource[methodName] = method; | ||
} | ||
else if (methodSchema.transformRequest) { | ||
var method = function () { | ||
var args = []; | ||
for (var _i = 0; _i < arguments.length; _i++) { | ||
args[_i] = arguments[_i]; | ||
} | ||
var transformedConfig = methodSchema.transformRequest.apply(methodSchema, args); | ||
return makeRequest(transformedConfig); | ||
}; | ||
resource[methodName] = method; | ||
} | ||
else if (methodSchema.transformResponse) { | ||
var method = function (config) { | ||
if (config === void 0) { config = {}; } | ||
return makeRequest(config).then(methodSchema.transformResponse); | ||
}; | ||
resource[methodName] = method; | ||
} | ||
else { | ||
resource[methodName] = makeRequest; | ||
} | ||
}; | ||
@@ -49,0 +85,0 @@ for (var _i = 0, _a = Object.keys(schema); _i < _a.length; _i++) { |
{ | ||
"name": "axios-rest-resource", | ||
"version": "0.5.0", | ||
"version": "0.6.0-rc.0", | ||
"description": "Schema-based HTTP client powered by axios. Built with Typescript. Heavily inspired by AngularJS' $resource.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -16,2 +16,3 @@ # axios-rest-resource [](https://travis-ci.org/keenondrums/axios-rest-resource) | ||
- [Rails Schema](#rails-schema) | ||
- [Request and Response Transforms](#request-and-response-transforms) | ||
- [In depth](#in-depth) | ||
@@ -227,2 +228,75 @@ | ||
### Request and Response Transforms | ||
You can add `transformRequest` and `transformResponse` functions to your schema methods to transform parameters into request config and response data into typed results. This can make the API for the resource much more natural, as it can accept and return sensible types rather than dealing with raw request configs and response data. | ||
```ts | ||
// api/users.ts | ||
import { resourceBuilder } from 'utils/resource' | ||
interface User { | ||
id: number | ||
email: string | ||
} | ||
interface SignInResponse { | ||
token: string | ||
user: User | ||
} | ||
export const usersResource = resourceBuilder.build('/users', { | ||
signIn: { | ||
method: 'post', | ||
url: '/sign_in', | ||
// Transform parameters into request config | ||
transformRequest: (email: string, password: string) => ({ | ||
data: { email, password }, | ||
headers: { 'X-Custom': 'test' }, | ||
}), | ||
// Transform response data into typed result | ||
transformResponse: (response): SignInResponse => ({ | ||
token: response.data.auth_token, | ||
user: { | ||
id: response.data.user.id, | ||
email: response.data.user.email, | ||
}, | ||
}), | ||
}, | ||
getProfile: { | ||
method: 'get', | ||
// Only transform response | ||
transformResponse: (response): User => ({ | ||
id: response.data.id, | ||
email: response.data.email, | ||
}), | ||
}, | ||
register: { | ||
method: 'post', | ||
// Only transform request | ||
transformRequest: (email: string, password: string) => ({ | ||
data: { email, password }, | ||
}), | ||
}, | ||
}) | ||
// Usage with full type inference | ||
const signInResult = await usersResource.signIn('email@example.com', 'password') | ||
console.log(signInResult.token) // string | ||
console.log(signInResult.user.id) // number | ||
const profile = await usersResource.getProfile() | ||
console.log(profile.email) // string | ||
const registerResult = await usersResource.register('email@example.com', 'password') | ||
console.log(registerResult.data) // axios response data | ||
``` | ||
The transforms provide: | ||
- Type-safe parameter transformation with optional parameters | ||
- Type-safe response data transformation | ||
- Custom headers support | ||
- Independent use of transforms (can use either or both) | ||
- Full TypeScript type inference for parameters and return types | ||
## In depth | ||
@@ -229,0 +303,0 @@ |
24468
230
324