Skip to content

Commit

Permalink
Merge pull request #3 from rambler-digital-solutions/transport
Browse files Browse the repository at this point in the history
feat(transport): add transport
  • Loading branch information
andrepolischuk committed Aug 15, 2024
2 parents 5e539ba + 5279ebd commit df11b53
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .size-limit.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
"path": "packages/splits/dist/index.js",
"limit": "1.6 KB"
},
{
"path": "packages/transport/dist/index.js",
"limit": "675 B"
},
{
"path": "packages/url/dist/index.js",
"limit": "675 B"
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Common utils used by Rambler team
- [@rambler-tech/react](packages/react)
- [@rambler-tech/session-storage](packages/session-storage)
- [@rambler-tech/splits](packages/splits)
- [@rambler-tech/transport](packages/transport)
- [@rambler-tech/url](packages/url)

## Contributing
Expand Down
15 changes: 15 additions & 0 deletions packages/transport/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# API transport

Enchanced API transport with timeout and query params

## Install

```
npm install -D @rambler-tech/transport
```

or

```
yarn add -D @rambler-tech/transport
```
73 changes: 73 additions & 0 deletions packages/transport/index.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {request} from '.'

const fetchMock = jest.fn(() =>
Promise.resolve({
status: 200,
json: () => Promise.resolve({data: 'baz'})
})
) as jest.Mock

beforeEach(() => {
jest.spyOn(global, 'fetch').mockImplementation(fetchMock)
})

test('base request api', async () => {
await request('/api', {})

expect(fetchMock).toHaveBeenCalledWith('/api', {
method: 'get',
headers: {
'Content-Type': 'application/json'
}
})
})

test('request api with query', async () => {
await request('/api', {
query: {
foo: 'bar'
}
})

expect(fetchMock).toHaveBeenCalledWith('/api?foo=bar', {
method: 'get',
headers: {
'Content-Type': 'application/json'
}
})
})

test('request api with query', async () => {
await request('/api', {
method: 'post',
body: {
foo: 'bar'
}
})

expect(fetchMock).toHaveBeenCalledWith('/api', {
method: 'post',
body: '{"foo":"bar"}',
headers: {
'Content-Type': 'application/json'
}
})
})

test('request api with timeout', async () => {
await request('/api', {
timeout: 1000
})

expect(fetchMock).toHaveBeenCalledWith('/api', {
method: 'get',
signal: expect.any(AbortSignal),
headers: {
'Content-Type': 'application/json'
}
})
})

afterEach(() => {
jest.clearAllMocks()
})
71 changes: 71 additions & 0 deletions packages/transport/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
/* eslint-disable import/no-unused-modules */

const OK = 200

/** Request options */
export interface RequestOptions extends Omit<RequestInit, 'body'> {
/** Request query params */
query?: Record<string, string>
/** Request body */
body?: Record<string, any> | BodyInit | null
/** Request timeout (ms) */
timeout?: number
}

/** Request */
export async function request<T>(
url = '',
requestOptions: RequestOptions = {}
): Promise<T> {
const {
method = 'get',
query = {},
body,
timeout,
headers,
...options
} = requestOptions

const requestInit: RequestInit = {
method,
...options,
headers: {
'Content-Type': 'application/json',
...headers
}
}

let requestUrl = url

if (query) {
const queryString = new URLSearchParams(query).toString()

if (queryString) {
requestUrl += `?${queryString}`
}
}

if (body) {
requestInit.body =
body instanceof FormData || typeof body === 'string'
? body
: JSON.stringify(body)
}

if (timeout != null) {
const controller = new AbortController()

requestInit.signal = controller.signal
window.setTimeout(() => controller.abort(), timeout)
}

const response = await fetch(requestUrl, requestInit)

if (response.status !== OK) {
throw new Error(
`Failed to fetch: ${response.status} ${response.statusText}`
)
}

return response.json()
}
12 changes: 12 additions & 0 deletions packages/transport/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"name": "@rambler-tech/transport",
"version": "0.0.0",
"main": "dist",
"module": "dist",
"types": "dist/index.d.ts",
"license": "MIT",
"sideEffects": false,
"publishConfig": {
"access": "public"
}
}
1 change: 1 addition & 0 deletions packages/transport/tsconfig.json
1 change: 1 addition & 0 deletions packages/transport/typedoc.json

0 comments on commit df11b53

Please sign in to comment.