Skip to content

Commit

Permalink
feat: add cron job endpoints (#18)
Browse files Browse the repository at this point in the history
* chore(types): added type definition for cron type

* lib(util): added request function generator for primitive endpoints

* feat: add cron function to class

* chore(release): bump package version to 1.3.0

* refractor: add better wording for function comment

* chore(tests): add tests for new primitive endpoint util
  • Loading branch information
fabio-nettis authored Apr 18, 2024
1 parent 68e2a32 commit 990a3fd
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 3 deletions.
27 changes: 26 additions & 1 deletion __tests__/utils/request-generator.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,36 @@ import "__mocks__/utils/request";

import {
generateDynamicRequestFn,
generatePrimitiveRequestFn,
generateSingleRequestFn,
} from "utils/request-generator";

import { it, expect } from "bun:test";
import type { Planet } from "types/api-entities";
import type { Cron, Planet } from "types/api-entities";

it("PrimitiveRequestFn works as expected", async () => {
// @ts-expect-error
const primitiveRequest = generatePrimitiveRequestFn<Cron>("/api/crons");

const response1 = await primitiveRequest("refresh_from_source");
const response2 = await primitiveRequest();

expect(response1.ok).toBe(true);
expect(response2.ok).toBe(true);

expect(response1.url).toBe("/api/crons/refresh_from_source");
expect(response2.url).toBe("/api/crons");

const json1 = await response1.json();
const json2 = await response2.json();

expect(json1).toHaveProperty("data", null);
expect(json1).toHaveProperty("error", null);

expect(json2).toHaveProperty("data", null);
expect(json2).toHaveProperty("error", null);
expect(json2).toHaveProperty("pagination", null);
});

it("SingleRequestFn works as expected", async () => {
const singleRequest = generateSingleRequestFn<Planet>("https://example.com");
Expand Down
13 changes: 12 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { request } from "utils/request";

import {
generateDynamicRequestFn,
generateSingleRequestFn,
generateDynamicRequestFn,
generatePrimitiveRequestFn,
} from "utils/request-generator";

import type {
War,
Stat,
Cron,
Biome,
Order,
Effect,
Expand Down Expand Up @@ -169,6 +171,15 @@ class SDK {
* Endpoint: `/api/effects(/:id)`
*/
effects = generateDynamicRequestFn<Effect>("effects");

/**
* ### Crons
*
* Allows you to track the internal cron jobs. Fine tune your periodic requests to the
* API and avoid hitting request limits by over fetching.
*/
// @ts-ignore
crons = generatePrimitiveRequestFn<Cron>("crons");
}

const HellHub = SDK.getInstance();
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"license": "MIT",
"private": false,
"description": "The official SDK for HellHub API. Filter and collect data with full type safety out of the box.",
"version": "1.2.1",
"version": "1.3.0",
"main": "dist/index.mjs",
"types": "dist/index.d.ts",
"keywords": [
Expand Down
12 changes: 12 additions & 0 deletions types/api-entities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,18 @@ import type { QueryOptions } from "types/query-generator";
* Base types
*/

export interface Cron {
name: string;
pattern: string;
status: "ok" | "stopped";
busy: boolean;
runs: {
next: number | null;
current: number | null;
previous: number | null;
};
}

export interface Entity {
id: number;
createdAt: string;
Expand Down
31 changes: 31 additions & 0 deletions utils/request-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,37 @@ import type {
APIRequestInit,
} from "types/api-entities";

/**
* Creates a request function for a given endpoint, which can be used to fetch
* from a endpoint that does not support any query parameters.
*/
export function generatePrimitiveRequestFn<T extends Entity>(entity: string) {
async function requestFn(
input?: Omit<APIRequestInit<T[]>, "query">,
options?: undefined,
): Promise<APIResponse<T[]>>;

async function requestFn(
input: number | string,
options?: Omit<APIRequestInit<T[]>, "query">,
): Promise<APIResponse<T>>;

async function requestFn(
input: Omit<APIRequestInit<T[]>, "query"> | undefined | number | string,
options?: APIRequestInit<T[]> | APIRequestInit<T>,
): Promise<APIResponse<T[]> | APIResponse<T>> {
if (typeof input === "object" || input === undefined) {
return request(entity, { ...input }) as Promise<APIResponse<T[]>>;
} else {
return request(`${entity}/${input}`, {
...(options as APIRequestInit<T>),
}) as Promise<APIResponse<T>>;
}
}

return requestFn;
}

/**
* Creates a request function for a given entity, which can be used to fetch
* data from the API.
Expand Down

0 comments on commit 990a3fd

Please sign in to comment.