Skip to content

Commit 71b81f6

Browse files
authored
Update v1.1.0 (#10)
Features - Add size to HawAPIOptions - Add PageableBuilder - Add setLanguage method Changes - Update typedoc config - Update buildUrl to overwrite values - Update filters value to be undefined or null - Update param language from getOverview be undefined - Replace null with undefined on RequestResult Fixes - Fix missing types export - Fix value `cached` from ResultRequest always being true
1 parent c022410 commit 71b81f6

13 files changed

Lines changed: 742 additions & 597 deletions

File tree

package.json

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@
3939
"exports": {
4040
".": [
4141
{
42+
"types": "./dist/types/index.d.ts",
4243
"import": "./dist/index.min.mjs",
4344
"require": "./dist/index.min.cjs",
4445
"default": "./dist/index.min.js"
4546
},
46-
"./dist/index.js"
47+
"./dist/index.min.js"
4748
]
4849
},
4950
"scripts": {
@@ -63,20 +64,20 @@
6364
"devDependencies": {
6465
"@mxssfd/typedoc-theme": "^1.1.2",
6566
"@rollup/plugin-terser": "^0.4.3",
66-
"@types/eslint": "^8.4.10",
67-
"@types/jest": "^29.2.4",
67+
"@types/eslint": "^8.44.2",
68+
"@types/jest": "^29.5.4",
6869
"@types/prettier": "^2.7.2",
6970
"@typescript-eslint/eslint-plugin": "^5.47.0",
7071
"@typescript-eslint/parser": "^5.47.0",
71-
"eslint": "^8.30.0",
72+
"eslint": "^8.48.0",
7273
"eslint-config-prettier": "^8.5.0",
7374
"eslint-plugin-prettier": "^4.2.1",
74-
"jest": "^29.3.1",
75+
"jest": "^29.6.4",
7576
"prettier": "^2.8.1",
7677
"rollup": "^2.79.1",
7778
"rollup-plugin-typescript2": "^0.34.1",
78-
"ts-jest": "^29.0.3",
79-
"ts-jest-resolver": "^2.0.0",
79+
"ts-jest": "^29.1.1",
80+
"ts-jest-resolver": "^2.0.1",
8081
"typedoc": "^0.24.8",
8182
"typescript": "^4.9.4"
8283
}

src/HawAPIClient.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import HawAPIOptions from './HawAPIOptions';
22
import { isValidTargetOrThrow } from './Utils';
33
import { InMemoryCacheManager } from './cache';
4-
import { EndpointType, Endpoints } from './enums/EndpointType';
4+
import { EndpointType, Endpoints } from './enums';
55
import { Filters, Pageable } from './filters';
66
import {
77
APIInfoModel,
@@ -71,7 +71,7 @@ export default class HawAPIClient {
7171

7272
/**
7373
* Method to get all client options
74-
* @returns
74+
* @returns The current {@link HawAPIOptions} (without token)
7575
*/
7676
public async getOptions(): Promise<HawAPIOptions> {
7777
return {
@@ -80,6 +80,13 @@ export default class HawAPIClient {
8080
};
8181
}
8282

83+
/**
84+
* Method to define new language into client options
85+
*/
86+
public async setLanguage(language: string): Promise<void> {
87+
this.options.language = language;
88+
}
89+
8390
/**
8491
* Method to clear all cached data
8592
* @returns The count of all cleaned data
@@ -120,9 +127,9 @@ export default class HawAPIClient {
120127
* @returns An new {@link RequestResult} with overview
121128
*/
122129
public async getOverview<OverviewModel>(
123-
language: string
130+
language?: string
124131
): Promise<RequestResult<OverviewModel>> {
125-
return this.service.fetch(`/overview`, { language }, null);
132+
return this.service.fetch(`/overview`, { language: language }, null);
126133
}
127134

128135
/**

src/HawAPIOptions.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { API_DEFAULT_LANG, API_URL, API_VERSION } from './Constants';
1+
import { API_URL, API_VERSION } from './Constants';
22

33
/**
44
* The HawAPI options configuration.
@@ -19,13 +19,22 @@ class HawAPIOptions {
1919
version: string = API_VERSION;
2020

2121
/**
22-
* The language of items in request
22+
* The language of items for all requests
2323
*
2424
* **Note: This value can be overwritten later**
2525
*
2626
* @default 'en-US'
2727
*/
28-
language: string;
28+
language?: string;
29+
30+
/**
31+
* The size of items for all requests
32+
*
33+
* **Note: This value can be overwritten later**
34+
*
35+
* @default 10
36+
*/
37+
size?: number;
2938

3039
/**
3140
* The timeout of a response in milliseconds
@@ -52,7 +61,6 @@ class HawAPIOptions {
5261
constructor(config: Partial<HawAPIOptions> = {}) {
5362
this.endpoint = API_URL;
5463
this.version = API_VERSION;
55-
this.language = API_DEFAULT_LANG;
5664
this.timeout = 10 * 1000;
5765
this.inMemoryCache = true;
5866

@@ -62,6 +70,8 @@ class HawAPIOptions {
6270

6371
if (config.language) this.language = config.language;
6472

73+
if (config.size) this.size = config.size;
74+
6575
if (config.timeout) this.timeout = config.timeout;
6676

6777
if (config.token) this.token = config.token;

src/Utils.ts

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,13 @@ export function buildResult<T>(
4040
const language = headers.get(API_HEADER_CONTENT_LANGUAGE);
4141

4242
return {
43-
page: Number(page) || null,
44-
page_size: Number(page_size) || null,
45-
page_total: Number(page_total) || null,
46-
item_size: Number(item_total) || null,
47-
next_page: handlePagination(Number(page), true) || null,
48-
prev_page: handlePagination(Number(page), false) || null,
49-
language: language || null,
43+
page: Number(page) || undefined,
44+
page_size: Number(page_size) || undefined,
45+
page_total: Number(page_total) || undefined,
46+
item_size: Number(item_total) || undefined,
47+
next_page: handlePagination(Number(page), true) || undefined,
48+
prev_page: handlePagination(Number(page), false) || undefined,
49+
language: language || undefined,
5050
status: status,
5151
data: body,
5252
};
@@ -89,33 +89,56 @@ export function buildUrl(
8989
filters?: Filters | null,
9090
pageable?: Pageable | null
9191
) {
92-
let params = '?';
92+
let params: string[] = [];
93+
94+
if (options.language) params.push(`language=${options.language}`);
95+
if (options.size) params.push(`size=${options.size}`);
9396

9497
// Get all filters names and values
9598
if (filters) {
9699
for (const key in filters) {
97100
const value = filters[key];
98101
if (value !== undefined && value !== null) {
99-
params += `${key}=${value}&`;
102+
params = pushOrOverwrite(params, key, value);
100103
}
101104
}
102105
}
103106

104107
// Define the page, sort and order
105108
if (pageable) {
106-
if (pageable.page) params += `page=${pageable.page}&`;
107-
if (pageable.size) params += `size=${pageable.size}&`;
109+
if (pageable.page) params = pushOrOverwrite(params, 'page', pageable.page);
110+
if (pageable.size) params = pushOrOverwrite(params, 'size', pageable.size);
108111

109112
// 'Order' can only be applied when 'sort' is defined
110113
if (pageable.sort) {
111114
if (pageable.order) {
112-
params += `sort=${pageable.sort},${pageable.order}&`;
115+
params = pushOrOverwrite(
116+
params,
117+
'sort',
118+
`${pageable.sort},${pageable.order}`
119+
);
113120
} else {
114-
params += `sort=${pageable.sort}&`;
121+
params = pushOrOverwrite(params, 'sort', pageable.sort);
115122
}
116123
}
117124
}
118125

119-
params = params.slice(0, -1);
120-
return options.endpoint + `/${options.version}${target}${params}`;
126+
const stringOfParams = params.length !== 0 ? '?' + params.join('&') : '';
127+
return options.endpoint + `/${options.version}${target}${stringOfParams}`;
128+
}
129+
130+
/**
131+
* Method to push new key/value or overwrite existing one
132+
* @param params A array of strings
133+
* @param key The param name
134+
* @param value The param value
135+
* @returns A array of strings with new key/value or overwritten value
136+
*/
137+
function pushOrOverwrite(params: string[], key: string, value: unknown) {
138+
const param = params.find((e) => e.includes(key));
139+
140+
if (param !== undefined) params[params.indexOf(param)] = `${key}=${value}`;
141+
else params.push(`${key}=${value}`);
142+
143+
return params;
121144
}

src/cache/InMemoryCacheManager.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,14 @@ export class InMemoryCacheManager {
3737
*
3838
* @param key The cache key
3939
* @param value The value to be cached
40+
* @returns true if {@link useCache} is true and the cache was added or false if {@link useCache} is false
4041
*/
41-
async set(key: string, value: RequestResult<unknown>): Promise<void> {
42+
async set(key: string, value: RequestResult<unknown>): Promise<boolean> {
4243
if (this.useCache) {
43-
this.storage.set(key, value);
44+
return this.storage.set(key, value) !== undefined;
4445
}
46+
47+
return false;
4548
}
4649

4750
/**

src/filters/Filters.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
* See more: {@link https://hawapi.theproject.id/docs/guides/filters}
66
*/
77
export type Filters = {
8-
[key: string]: string;
8+
[key: string]: string | undefined | null;
99
};

src/filters/Pageable.ts

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,39 @@ export class Pageable {
4949

5050
if (pageable.order) this.order = pageable.order;
5151
}
52+
53+
/**
54+
* A fluent builder for configuring Pageable
55+
*/
56+
static Builder = class PageableBuilder {
57+
private pageable: Pageable = new Pageable({});
58+
59+
page(value: number) {
60+
this.pageable.page = value;
61+
return this;
62+
}
63+
64+
size(value: number) {
65+
this.pageable.size = value;
66+
return this;
67+
}
68+
69+
order(value: OrderType) {
70+
this.pageable.order = value;
71+
return this;
72+
}
73+
74+
sort(value: string) {
75+
this.pageable.sort = value;
76+
return this;
77+
}
78+
79+
/**
80+
* Converts the pageable builder into {@link Pageable}
81+
* @returns A new {@link Pageable}
82+
*/
83+
build(): Pageable {
84+
return new Pageable(this.pageable);
85+
}
86+
};
5287
}

src/models/http/RequestResult.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,44 +5,44 @@ export interface RequestResult<T> {
55
/**
66
* The current page index
77
*/
8-
page?: number | null;
8+
page?: number | undefined;
99

1010
/**
1111
* The item size of current page
1212
*/
13-
page_size?: number | null;
13+
page_size?: number | undefined;
1414

1515
/**
1616
* The total of pages
1717
*/
18-
page_total?: number | null;
18+
page_total?: number | undefined;
1919

2020
/**
2121
* The total of items in the database
2222
*/
23-
item_size?: number | null;
23+
item_size?: number | undefined;
2424

2525
/**
2626
* The next page index
2727
*/
28-
next_page?: number | null;
28+
next_page?: number | undefined;
2929

3030
/**
3131
* The previous page index
3232
*/
33-
prev_page?: number | null;
33+
prev_page?: number | undefined;
3434

3535
/**
3636
* The content language
3737
*
3838
* {@link HawAPIOptions}
3939
*/
40-
language?: string | null;
40+
language?: string | undefined;
4141

4242
/**
4343
* The request status code
4444
*/
45-
status?: number | null;
45+
status: number;
4646

4747
/**
4848
* Determine if data is from cache

src/service/Service.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export class Service {
3434
const url = buildUrl(baseUrl, this.options, filters, pageable);
3535

3636
const cache = await this.cache.get<T>(url);
37-
if (cache !== undefined) return { ...cache, cached: true };
37+
if (cache !== undefined) return { cached: true, ...cache };
3838

3939
// Setup timeout
4040
let timeout;
@@ -59,9 +59,8 @@ export class Service {
5959
response.status
6060
);
6161

62-
await this.cache.set(url, result);
63-
64-
return { ...result, cached: true };
62+
const cached = await this.cache.set(url, result);
63+
return { cached, ...result };
6564
} catch (err) {
6665
const isJson = response.headers.get('Content-Type') == 'application/json';
6766

test/HawAPIClient.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ test('it use default client options', async () => {
1313

1414
expect(options.endpoint).toBe('https://hawapi.theproject.id/api');
1515
expect(options.version).toBe('v1');
16-
expect(options.language).toBe('en-US');
16+
expect(options.language).toBeUndefined();
17+
expect(options.size).toBeUndefined();
1718
expect(options.timeout).toBe(10000);
1819
expect(options.token).toBe('');
1920
expect(options.inMemoryCache).toBe(true);

0 commit comments

Comments
 (0)