diff --git a/README.md b/README.md index 4717b43..c41edd6 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ UN Notice -A TypeScript library for easily interacting with the Interpol public Notices API. This library provides a convenient, type-safe way to access data on Red, Yellow, and possibly in the future, other Interpol notices. +A TypeScript library for easily interacting with the Interpol public Notices API. This library provides a convenient, type-safe way to access data on Red, Yellow Interpol notices, and INTERPOL-United Nations Security Council Special Notices. ## Contents @@ -66,22 +66,22 @@ It is important to note that Interpol notices are not international arrest warra ## Development Status -Currently, this library focuses on retrieving and interacting with **Red Notices**. Support for **Yellow** and **UN Notices** is planned for future releases but is not yet implemented. Contributions are welcome to accelerate the development of these features! +This library currently supports retrieving and interacting with **Red Notices** and **Yellow Notices**. Support for **INTERPOL-United Nations Security Council Special Notices** is planned for future releases but is not yet implemented. Contributions are welcome to accelerate the development of these features! You can track the progress of these planned features in the project's issue tracker. We encourage community involvement in prioritizing and implementing support for additional notice types. ## Installation ```bash -npm install @jakubrekowski/interpol.ts +npm install interpol.ts # or -yarn add @jakubrekowski/interpol.ts +yarn add interpol.ts ``` ## Usage ```typescript -import { InterpolService } from "@jakubrekowski/interpol.ts"; +import { InterpolService } from "interpol.ts"; async function getRedNotices() { try { @@ -146,26 +146,47 @@ cancelRedNoticeRequest(); ## API Reference -### `InterpolService.getRedNotices(query?: RedNoticesQuery): CancelablePromise` +### `InterpolService.getRedNotices(query?: RedNoticesQuery): CancelablePromise` Retrieves a list of Red Notices. - **`query`**: Optional query parameters to filter the results (see `RedNoticesQuery` interface below). -- **Returns**: A `CancelablePromise` that resolves to a `RedNoticesEntitiy` object. +- **Returns**: A `CancelablePromise` that resolves to a `RedNoticesEntity` object. -### `InterpolService.getRedNoticeDetails(noticeID: string): CancelablePromise` +### `InterpolService.getRedNoticeDetails(noticeID: string): CancelablePromise` Retrieves details for a specific Red Notice. - **`noticeID`**: The ID of the Red Notice. -- **Returns**: A `CancelablePromise` that resolves to a `RedNoticeDetailsEntitiy` object. +- **Returns**: A `CancelablePromise` that resolves to a `RedNoticeDetailsEntity` object. -### `InterpolService.getRedNoticeDetailImages(noticeID: string): CancelablePromise` +### `InterpolService.getRedNoticeDetailImages(noticeID: string): CancelablePromise` Retrieves images for a specific Red Notice. - **`noticeID`**: The ID of the Red Notice. -- **Returns**: A `CancelablePromise` that resolves to a `RedNoticeDetailImagesEntitiy` object. +- **Returns**: A `CancelablePromise` that resolves to a `RedNoticeDetailImagesEntity` object. + +### `InterpolService.getYellowNotices(query?: YellowNoticesQuery): CancelablePromise` + +Retrieves a list of Yellow Notices. + +- **`query`**: Optional query parameters to filter the results (see `YellowNoticesQuery` interface below). +- **Returns**: A `CancelablePromise` that resolves to a `YellowNoticesEntity` object. + +### `InterpolService.getYellowNoticeDetails(noticeID: string): CancelablePromise` + +Retrieves details for a specific Yellow Notice. + +- **`noticeID`**: The ID of the Yellow Notice. +- **Returns**: A `CancelablePromise` that resolves to a `YellowNoticeDetailsEntity` object. + +### `InterpolService.getYellowNoticeDetailImages(noticeID: string): CancelablePromise` + +Retrieves images for a specific Yellow Notice. + +- **`noticeID`**: The ID of the Yellow Notice. +- **Returns**: A `CancelablePromise` that resolves to a `YellowNoticeDetailImagesEntity` object. ### `RedNoticesQuery` Interface @@ -180,7 +201,23 @@ interface RedNoticesQuery { sexId?: "F" | "M" | "U"; // Sex ID arrestWarrantCountryId?: string; // Country ID of arrest warrant (two-digit country code) page?: number; // Page number for pagination - resultPerPage?: number; // Number of results per page + resultPerPage?: number; // Number of results per page; maximum is 160 +} +``` + +### `YellowNoticesQuery` Interface + +```typescript +interface YellowNoticesQuery { + forename?: string; // First name + name?: string; // Last name + nationality?: string; // Nationality (two-digit country code) + ageMax?: number; // Maximum age + ageMin?: number; // Minimum age + freeText?: string; // Free text search + sexId?: "F" | "M" | "U"; // Sex ID + page?: number; // Page number for pagination + resultPerPage?: number; // Number of results per page; maximum is 160 } ``` diff --git a/src/models/RedNoticeDetailImages.ts b/src/models/RedNoticeDetailImages.ts index 3cf29c8..50031f8 100644 --- a/src/models/RedNoticeDetailImages.ts +++ b/src/models/RedNoticeDetailImages.ts @@ -1,7 +1,7 @@ /** * Represents the Red Notice Detail Images. */ -export type RedNoticeDetailImagesEntitiy = { +export type RedNoticeDetailImagesEntity = { /** * Contains embedded images. */ diff --git a/src/models/RedNoticeDetails.ts b/src/models/RedNoticeDetails.ts index 5b3839d..d96145e 100644 --- a/src/models/RedNoticeDetails.ts +++ b/src/models/RedNoticeDetails.ts @@ -1,7 +1,7 @@ /** * Represents the details of a Red Notice entity. */ -export type RedNoticeDetailsEntitiy = { +export type RedNoticeDetailsEntity = { /** * List of arrest warrants associated with the entity. */ diff --git a/src/models/RedNotices.ts b/src/models/RedNotices.ts index 191e32e..b28a1bd 100644 --- a/src/models/RedNotices.ts +++ b/src/models/RedNotices.ts @@ -47,7 +47,7 @@ export interface RedNoticesQuery { /** * Represents a collection of Red Notices. */ -export type RedNoticesEntitiy = { +export type RedNoticesEntity = { /** * The total number of Red Notices. */ diff --git a/src/models/YellowNoticeDetailImages.ts b/src/models/YellowNoticeDetailImages.ts new file mode 100644 index 0000000..0252ef0 --- /dev/null +++ b/src/models/YellowNoticeDetailImages.ts @@ -0,0 +1,53 @@ +/** + * Represents the Yellow Notice Detail Images. + */ +export type YellowNoticeDetailImagesEntity = { + /** + * Contains embedded images. + */ + _embedded: { + /** + * Array of image objects. + */ + images: { + /** + * The ID of the picture. + */ + picture_id: string; + /** + * Links related to the image. + */ + _links: { + /** + * Link to the image itself. + */ + self: { + href: string; + }; + }; + }[]; + }; + /** + * Links related to the yellow notice. + */ + _links: { + /** + * Link to the yellow notice detail images. + */ + self: { + href: string; + }; + /** + * Link to the notice. + */ + notice: { + href: string; + }; + /** + * Link to the thumbnail image. + */ + thumbnail: { + href: string; + }; + }; +}; diff --git a/src/models/YellowNoticeDetails.ts b/src/models/YellowNoticeDetails.ts new file mode 100644 index 0000000..8d12893 --- /dev/null +++ b/src/models/YellowNoticeDetails.ts @@ -0,0 +1,118 @@ +/** + * Represents the details of a Yellow Notice entity. + */ +export type YellowNoticeDetailsEntity = { + /** + * The country associated with the entity. Two digit country code. + */ + country: string; + /** + * The date of birth of the entity. + */ + date_of_birth?: string; + /** + * The name of the entity's mother. + */ + mother_name?: string; + /** + * List of countries likely to be visited by the entity. Two digit country code. + */ + countries_likely_to_be_visited: string[]; + /** + * The forename of the entity's mother. + */ + mother_forename?: string; + /** + * The nationalities of the entity. Two digit country code. + */ + nationalities: string[]; + /** + * The ID representing the eye color of the entity. + */ + eye_colors_id?: string; + /** + * The sex of the entity. + */ + sex_id?: "F" | "M" | "U"; + /** + * The ID representing the hair type of the entity. + */ + hairs_id?: string; + /** + * The place associated with the entity. + */ + place: string; + /** + * List of IDs representing languages spoken by the entity. Three digit language code. + */ + language_spoken_ids: string[]; + /** + * The date of the event related to the entity. + */ + date_of_event?: string; + /** + * The height of the entity. + */ + height?: number; + /** + * The forename of the entity's father. + */ + father_forename?: string; + /** + * Distinguishing marks of the entity. + */ + distinguishing_marks?: string; + /** + * The birth name of the entity. + */ + birth_name?: string; + /** + * The weight of the entity. + */ + weight?: number; + /** + * The unique identifier for the entity. + */ + entity_id: string; + /** + * The place of birth of the entity. + */ + place_of_birth?: string; + /** + * The name of the entity's father. + */ + father_name?: string; + /** + * The name of the entity. + */ + name: string; + _embedded: { + /** + * Array of link URLs. + */ + links: string[]; + }; + /** + * Hyperlinks related to the entity. + */ + _links: { + /** + * The self-reference hyperlink. + */ + self: { + href: string; + }; + /** + * Link to images associated with the entity. + */ + images: { + href: string; + }; + /** + * Link to the thumbnail image associated with the entity. + */ + thumbnail: { + href: string; + }; + }; +}; diff --git a/src/models/YellowNotices.ts b/src/models/YellowNotices.ts new file mode 100644 index 0000000..c037d6d --- /dev/null +++ b/src/models/YellowNotices.ts @@ -0,0 +1,171 @@ +/** + * Represents a query for Yellow Notices. + */ +export interface YellowNoticesQuery { + /** + * The first name of the individual. + */ + forename?: string; + /** + * The last name of the individual. + */ + name?: string; + /** + * The nationality of the individual. Two digit country code. + */ + nationality?: string; + /** + * The maximum age of the individual. + */ + ageMax?: number; + /** + * The minimum age of the individual. + */ + ageMin?: number; + /** + * Free text for the query. + */ + freeText?: string; + /** + * The sex ID of the individual. + */ + sexId?: "F" | "M" | "U"; + /** + * The country ID of the arrest warrant. Two digit country code. + */ + arrestWarrantCountryId?: string; + /** + * The page number for pagination. + */ + page?: number; + /** + * The number of results per page. + */ + resultPerPage?: number; +} + +/** + * Represents a collection of Yellow Notices. + */ +export type YellowNoticesEntity = { + /** + * The total number of Yellow Notices. + */ + total: number; + /** + * The query used to retrieve the Yellow Notices. + */ + query: YellowNoticesQuery; + /** + * The embedded Yellow Notices. + */ + _embedded: { + /** + * An array of Yellow Notices. + */ + notices: { + /** + * The date of birth of the subject of the Red Notice. YYYY/MM/DD. + */ + date_of_birth: string; + /** + * The nationalities of the subject of the Red Notice. Two digit country code. + */ + nationalities: string[]; + /** + * The unique identifier for the entity. + */ + entity_id: string; + /** + * The first name of the subject of the Red Notice. + */ + forename: string; + /** + * The last name of the subject of the Red Notice. + */ + name: string; + /** + * Links to related resources. + */ + _links: { + /** + * Link to the Red Notice itself. + */ + self: { + /** + * The URL of the Red Notice. + */ + href: string; + }; + /** + * Link to images of the subject of the Red Notice. + */ + images: { + /** + * The URL of the images. + */ + href: string; + }; + /** + * Link to a thumbnail image of the subject of the Red Notice. + */ + thumbnail: { + /** + * The URL of the thumbnail image. + */ + href: string; + }; + }; + }[]; + }; + /** + * Links to related resources. + */ + _links: { + /** + * Link to the current page of Yellow Notices. + */ + self: { + /** + * The URL of the current page. + */ + href: string; + }; + /** + * Link to the first page of Yellow Notices. + */ + first: { + /** + * The URL of the first page. + */ + href: string; + }; + /** + * Link to the previous page of Yellow Notices. + */ + previous?: { + /** + * The URL of the previous page. + */ + href: string; + }; + /** + * Link to the next page of Yellow Notices. + */ + next?: { + /** + * The URL of the next page. + */ + href: string; + }; + /** + * Link to the last page of Yellow Notices. + */ + last: { + /** + * The URL of the last page. + */ + href: string; + }; + }; +}; diff --git a/src/services/InterpolService.test.ts b/src/services/InterpolService.test.ts index 8184333..0684aa0 100644 --- a/src/services/InterpolService.test.ts +++ b/src/services/InterpolService.test.ts @@ -55,4 +55,59 @@ describe("InterpolService", () => { await expect(InterpolService.getRedNoticeDetailImages("invalid-notice-id")).rejects.toThrow(); }); }); + + describe("getYellowNotices", () => { + it("should return yellow notices when API call is successful", async () => { + const yellowNotices = await InterpolService.getYellowNotices(); + expect(yellowNotices).toBeDefined(); + expect(Array.isArray(yellowNotices._embedded.notices)).toBe(true); + expect(yellowNotices._embedded.notices.length).toBeGreaterThan(0); + + if (yellowNotices._embedded.notices.length > 0) { + noticeID = yellowNotices._embedded.notices[0].entity_id.replace("/", "-"); + expect(noticeID).toBeTruthy(); + } else { + console.warn("No yellow notices found. Subsequent tests may fail."); + } + }); + + it("should handle empty result", async () => { + const yellowNotices = await InterpolService.getYellowNotices({ + name: "imposibble-name", + }); + expect(yellowNotices).toBeDefined(); + expect(Array.isArray(yellowNotices._embedded.notices)).toBe(true); + expect(yellowNotices._embedded.notices.length).toBe(0); + }); + }); + + describe("getYellowNoticeDetails", () => { + it("should return yellow notice details when API call is successful", async () => { + expect(noticeID).toBeTruthy(); + + const noticeDetails = await InterpolService.getYellowNoticeDetails(noticeID); + expect(noticeDetails).toBeDefined(); + expect(noticeDetails.entity_id).toBe(noticeID.replace("-", "/")); + }); + + it("should throw an error when API call fails by providing an invalid notice ID", async () => { + await expect(InterpolService.getYellowNoticeDetails("invalid-notice-id")).rejects.toThrow(); + }); + }); + + describe("getYellowNoticeDetailImages", () => { + it("should return yellow notice detail images when API call is successful", async () => { + expect(noticeID).toBeTruthy(); + + const images = await InterpolService.getYellowNoticeDetailImages(noticeID); + expect(images).toBeDefined(); + expect(Array.isArray(images._embedded.images)).toBe(true); + }); + + it("should throw an error when API call fails by providing an invalid notice ID", async () => { + await expect( + InterpolService.getYellowNoticeDetailImages("invalid-notice-id"), + ).rejects.toThrow(); + }); + }); }); diff --git a/src/services/InterpolService.ts b/src/services/InterpolService.ts index c0fca18..f6cd227 100644 --- a/src/services/InterpolService.ts +++ b/src/services/InterpolService.ts @@ -1,12 +1,15 @@ import type { CancelablePromise } from "../core/CancelablePromise"; import { OpenAPI } from "../core/OpenAPI"; import { request as __request } from "../core/request"; -import { RedNoticeDetailImagesEntitiy } from "../models/RedNoticeDetailImages"; -import { RedNoticeDetailsEntitiy } from "../models/RedNoticeDetails"; -import type { RedNoticesEntitiy, RedNoticesQuery } from "../models/RedNotices"; +import { RedNoticeDetailImagesEntity } from "../models/RedNoticeDetailImages"; +import { RedNoticeDetailsEntity } from "../models/RedNoticeDetails"; +import type { RedNoticesEntity, RedNoticesQuery } from "../models/RedNotices"; +import { YellowNoticeDetailImagesEntity } from "../models/YellowNoticeDetailImages"; +import { YellowNoticeDetailsEntity } from "../models/YellowNoticeDetails"; +import { YellowNoticesEntity, YellowNoticesQuery } from "../models/YellowNotices"; export class InterpolService { - public static getRedNotices(query?: RedNoticesQuery): CancelablePromise { + public static getRedNotices(query?: RedNoticesQuery): CancelablePromise { return __request(OpenAPI, { method: "GET", url: "/notices/v1/red", @@ -14,7 +17,7 @@ export class InterpolService { }); } - public static getRedNoticeDetails(noticeID: string): CancelablePromise { + public static getRedNoticeDetails(noticeID: string): CancelablePromise { return __request(OpenAPI, { method: "GET", url: "/notices/v1/red/{noticeID}", @@ -26,7 +29,7 @@ export class InterpolService { public static getRedNoticeDetailImages( noticeID: string, - ): CancelablePromise { + ): CancelablePromise { return __request(OpenAPI, { method: "GET", url: "/notices/v1/red/{noticeID}/images", @@ -35,4 +38,38 @@ export class InterpolService { }, }); } + + public static getYellowNotices( + query?: YellowNoticesQuery, + ): CancelablePromise { + return __request(OpenAPI, { + method: "GET", + url: "/notices/v1/yellow", + query, + }); + } + + public static getYellowNoticeDetails( + noticeID: string, + ): CancelablePromise { + return __request(OpenAPI, { + method: "GET", + url: "/notices/v1/yellow/{noticeID}", + path: { + noticeID, + }, + }); + } + + public static getYellowNoticeDetailImages( + noticeID: string, + ): CancelablePromise { + return __request(OpenAPI, { + method: "GET", + url: "/notices/v1/yellow/{noticeID}/images", + path: { + noticeID, + }, + }); + } }