Skip to content

Commit c1d3f90

Browse files
authored
refractor: improve general code quality (#13)
* refractor: remove duplicate type definition * chore(types): add foreign key fields to types * refractor: remove unused dependency * refractor: remove unused module declaration * feat: add mock for request utility * chore(tests): add test for utilities and main class * chore(publish): bump package version to 1.0.4
1 parent bc815c6 commit c1d3f90

File tree

10 files changed

+142
-17
lines changed

10 files changed

+142
-17
lines changed

__mocks__/utils/request.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { mock } from "bun:test";
2+
3+
import buildQuery from "utils/query-generator";
4+
import type { APIRequestInit, Entity } from "types/api-entities";
5+
6+
mock.module("utils/request", () => ({
7+
request: async <T extends Entity = any>(
8+
_url: any,
9+
_options: APIRequestInit<T> = {},
10+
) => {
11+
return {
12+
ok: true,
13+
url: `${_url}${
14+
_options.query && Object.keys(_options.query).length
15+
? `?${buildQuery(_options.query)}`
16+
: ""
17+
}`,
18+
json: async () => ({ data: null, error: null, pagination: null }),
19+
};
20+
},
21+
}));

__tests__/classes/export.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import "__mocks__/utils/request";
2+
3+
import HellHub from "index";
4+
import { it } from "bun:test";
5+
6+
it("Main class correctly infers types", async () => {
7+
const response = await HellHub.planets(1);
8+
const { data: _ } = await response.json();
9+
});
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { it, expect } from "bun:test";
2+
3+
import buildQuery from "utils/query-generator";
4+
import type { Planet } from "types/api-entities";
5+
6+
it("Query generator works as expected", () => {
7+
const query = buildQuery<Planet[]>({
8+
limit: 10,
9+
filters: { name: { $contains: "earth" } },
10+
});
11+
12+
expect(query).toBe("limit=10&filters[name][contains]=earth");
13+
});
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import "__mocks__/utils/request";
2+
3+
import {
4+
generateDynamicRequestFn,
5+
generateSingleRequestFn,
6+
} from "utils/request-generator";
7+
8+
import { it, expect } from "bun:test";
9+
import type { Planet } from "types/api-entities";
10+
11+
it("SingleRequestFn works as expected", async () => {
12+
const singleRequest = generateSingleRequestFn<Planet>("https://example.com");
13+
14+
const response = await singleRequest({
15+
query: {
16+
limit: 10,
17+
filters: { name: { $contains: "earth" } },
18+
},
19+
});
20+
21+
expect(response.ok).toBe(true);
22+
23+
expect(response.url).toBe(
24+
"https://example.com?limit=10&filters[name][contains]=earth",
25+
);
26+
27+
const json = await response.json();
28+
expect(json).toHaveProperty("data", null);
29+
expect(json).toHaveProperty("error", null);
30+
});
31+
32+
it("DynamicRequestFn works as expected", async () => {
33+
const dynamicRequest = generateDynamicRequestFn<Planet>(
34+
"https://example.com",
35+
);
36+
37+
const response = await dynamicRequest({
38+
limit: 10,
39+
filters: { name: { $contains: "earth" } },
40+
});
41+
42+
expect(response.ok).toBe(true);
43+
44+
expect(response.url).toBe(
45+
"https://example.com?limit=10&filters[name][contains]=earth",
46+
);
47+
48+
const json = await response.json();
49+
expect(json).toHaveProperty("data", null);
50+
expect(json).toHaveProperty("error", null);
51+
expect(json).toHaveProperty("pagination", null);
52+
});

__tests__/utils/request.test.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import "__mocks__/utils/request";
2+
3+
import { it, expect } from "bun:test";
4+
import { request } from "utils/request";
5+
import type { Planet } from "types/api-entities";
6+
7+
it("Request util works as expected", async () => {
8+
const response = await request<Planet[]>("https://example.com", {
9+
query: {
10+
limit: 10,
11+
filters: { name: { $contains: "earth" } },
12+
},
13+
});
14+
15+
expect(response.ok).toBe(true);
16+
17+
expect(response.url).toBe(
18+
"https://example.com?limit=10&filters[name][contains]=earth",
19+
);
20+
21+
expect(await response.json()).toEqual({
22+
data: null,
23+
error: null,
24+
pagination: null as any,
25+
});
26+
});

bun.lockb

-688 Bytes
Binary file not shown.

package.json

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"license": "MIT",
44
"private": false,
55
"description": "The official SDK for HellHub API. Filter and collect data with full type safety out of the box.",
6-
"version": "1.0.3",
6+
"version": "1.0.4",
77
"main": "dist/index.mjs",
88
"types": "dist/index.d.ts",
99
"keywords": [
@@ -46,8 +46,5 @@
4646
"author": {
4747
"name": "Fabio Nettis",
4848
"email": "nettisfabio@gmail.com"
49-
},
50-
"dependencies": {
51-
"fast-qs": "^1.0.2"
5249
}
5350
}

types/api-entities.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ export interface Faction extends RemoteEntity {
4141
export interface Planet extends RemoteEntity {
4242
name: string;
4343
owner?: Faction;
44+
ownerId: number;
4445
sector: Sector;
46+
sectorId: number;
4547
health: number;
4648
orders?: Order[];
4749
maxHealth: number;
@@ -50,18 +52,22 @@ export interface Planet extends RemoteEntity {
5052
positionX: number;
5153
positionY: number;
5254
statistics?: Stat;
55+
statisticId: number;
5356
attacking: Attack[];
5457
defending: Attack[];
5558
campaign?: Campaign;
5659
regeneration: number;
5760
homeWorld?: HomeWorld;
5861
initialOwner?: Faction;
62+
initialOwnerId: number;
5963
globalEvent?: GlobalEvent;
64+
globalEventId: number;
6065
}
6166

6267
export interface GlobalEvent extends RemoteEntity {
6368
title: string;
6469
faction?: Faction;
70+
factionId: number;
6571
message: string;
6672
planets: Planet[];
6773
}
@@ -70,23 +76,31 @@ export interface Campaign extends RemoteEntity {
7076
type: number;
7177
count: number;
7278
planet?: Planet;
79+
planetId: number;
7380
orders?: Order[];
7481
}
7582

7683
export interface HomeWorld extends RemoteEntity {
7784
faction?: Faction;
85+
factionId: number;
7886
planet?: Planet;
87+
planetId: number;
7988
}
8089

8190
export interface Attack extends RemoteEntity {
8291
target?: Planet;
92+
targetId: number;
8393
source?: Planet;
94+
sourceId: number;
8495
}
8596

8697
export interface Order extends RemoteEntity {
8798
planet?: Planet;
99+
planetId?: number;
88100
faction?: Faction;
101+
factionId?: number;
89102
campaign?: Campaign;
103+
campaignId?: number;
90104
eventType: "DEFEND" | "ATTACK";
91105
health: number;
92106
maxHealth: number;
@@ -146,6 +160,7 @@ export interface Assignment extends RemoteEntity {
146160
title: string;
147161
briefing: string;
148162
reward?: Reward;
163+
rewardId: number;
149164
progress: number;
150165
expiresAt: string;
151166
description: string;

types/fast-qs.ts

Lines changed: 0 additions & 3 deletions
This file was deleted.

types/query-generator.ts

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,18 @@ export type FieldOperator<T, K extends keyof T> = {
2929
$equals?: T[K];
3030
$in?: Array<T[K]>;
3131
$notIn?: Array<T[K]>;
32+
$lt?: T[K];
33+
$gt?: T[K];
34+
$lte?: T[K];
35+
$gte?: T[K];
3236
} & (T[K] extends string
3337
? {
3438
$search?: T[K];
3539
$contains?: T[K];
3640
$endsWith?: T[K];
3741
$startsWith?: T[K];
38-
$lt?: T[K];
39-
$gt?: T[K];
40-
$lte?: T[K];
41-
$gte?: T[K];
4242
}
43-
: {
44-
$lt?: T[K];
45-
$gt?: T[K];
46-
$lte?: T[K];
47-
$gte?: T[K];
48-
});
43+
: {});
4944

5045
export interface RootOperator<T> {
5146
$or?: Array<Filter<Defined<T>>>;

0 commit comments

Comments
 (0)