From 990a3fdf958cb3e37456157d422edb981e5cc514 Mon Sep 17 00:00:00 2001 From: Fabio Nettis Date: Thu, 18 Apr 2024 10:37:42 +0200 Subject: [PATCH] feat: add cron job endpoints (#18) * 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 --- __tests__/utils/request-generator.test.ts | 27 +++++++++++++++++++- index.ts | 13 +++++++++- package.json | 2 +- types/api-entities.ts | 12 +++++++++ utils/request-generator.ts | 31 +++++++++++++++++++++++ 5 files changed, 82 insertions(+), 3 deletions(-) diff --git a/__tests__/utils/request-generator.test.ts b/__tests__/utils/request-generator.test.ts index b07f775..8a9298d 100644 --- a/__tests__/utils/request-generator.test.ts +++ b/__tests__/utils/request-generator.test.ts @@ -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("/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("https://example.com"); diff --git a/index.ts b/index.ts index afe0d15..cc48e7f 100644 --- a/index.ts +++ b/index.ts @@ -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, @@ -169,6 +171,15 @@ class SDK { * Endpoint: `/api/effects(/:id)` */ effects = generateDynamicRequestFn("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("crons"); } const HellHub = SDK.getInstance(); diff --git a/package.json b/package.json index 6a3082d..42605e6 100644 --- a/package.json +++ b/package.json @@ -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": [ diff --git a/types/api-entities.ts b/types/api-entities.ts index 8064042..20ebe31 100644 --- a/types/api-entities.ts +++ b/types/api-entities.ts @@ -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; diff --git a/utils/request-generator.ts b/utils/request-generator.ts index f619c8c..0a79247 100644 --- a/utils/request-generator.ts +++ b/utils/request-generator.ts @@ -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(entity: string) { + async function requestFn( + input?: Omit, "query">, + options?: undefined, + ): Promise>; + + async function requestFn( + input: number | string, + options?: Omit, "query">, + ): Promise>; + + async function requestFn( + input: Omit, "query"> | undefined | number | string, + options?: APIRequestInit | APIRequestInit, + ): Promise | APIResponse> { + if (typeof input === "object" || input === undefined) { + return request(entity, { ...input }) as Promise>; + } else { + return request(`${entity}/${input}`, { + ...(options as APIRequestInit), + }) as Promise>; + } + } + + return requestFn; +} + /** * Creates a request function for a given entity, which can be used to fetch * data from the API.