@ipetsadmin/api-client 1.0.0 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +69 -310
- package/dist/index.d.mts +30 -3
- package/dist/index.d.ts +30 -3
- package/dist/index.js +75 -3
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +68 -4
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -19,6 +19,34 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
19
19
|
|
|
20
20
|
### Security
|
|
21
21
|
|
|
22
|
+
## [1.1.1] - 2026-04-25
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- **`HttpPatch`** and **`HttpClient.patch`** for JSON bodies (Axios-compatible), used by email verification.
|
|
27
|
+
- **`patchVerifyEmail`** — `PATCH /api/v1/auth/verify-email` (`VerifyEmailRequest` from `@ipetsadmin/contracts`). Exposed as **`api.auth.verifyEmail`** and as a named export.
|
|
28
|
+
- **`fetchHealthCheck`** (`src/endpoints/health-check.ts`) — `GET /api/v1/health-check` returning **`IApiResponse<HealthCheck>`**.
|
|
29
|
+
- **`createApiClient`** exposes **`healthCheck()`** delegating to **`fetchHealthCheck`**.
|
|
30
|
+
|
|
31
|
+
### Changed
|
|
32
|
+
|
|
33
|
+
- **`HttpClient`** now requires **`patch`** in addition to **`get`** and **`post`** (breaking for custom HTTP adapters that only implemented **`get`** / **`post`**).
|
|
34
|
+
- **Dev dependency** on **`@ipetsadmin/contracts`** raised to **1.1.7** for typings (`VerifyEmailRequest`, etc.). **Peer dependency** remains **`>= 1.1.1`**; use a contracts version that includes **`VerifyEmailRequest`** if you call **`patchVerifyEmail`**.
|
|
35
|
+
|
|
36
|
+
## [1.1.0] - 2026-04-04
|
|
37
|
+
|
|
38
|
+
### Added
|
|
39
|
+
|
|
40
|
+
- **`HttpClient.post`** and **`HttpPost`** type for JSON bodies (Axios-compatible).
|
|
41
|
+
- **Auth endpoints** (`src/endpoints/auth.ts`): `postRegister`, `postLogin`, `getGoogleOAuthStart`, `postGoogleOAuthCallback`, `postRefresh`, `postLogout`, `getMe`.
|
|
42
|
+
- **`createApiClient`** exposes **`auth`** namespace delegating to the auth endpoints.
|
|
43
|
+
- **Peer dependency** on `@ipetsadmin/contracts` **≥ 1.1.1** (align with service ports and Auth0 helper types on the API).
|
|
44
|
+
- README updated with endpoint table and OAuth flow notes.
|
|
45
|
+
|
|
46
|
+
### Changed
|
|
47
|
+
|
|
48
|
+
- **`createApiClient`** now requires an `http` implementation that provides both **`get`** and **`post`** (breaking for consumers that only implemented `get`).
|
|
49
|
+
|
|
22
50
|
## [1.0.0] - 2026-04-02
|
|
23
51
|
|
|
24
52
|
### Added
|
package/README.md
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# `@ipetsadmin/api-client`
|
|
2
2
|
|
|
3
|
-
Typed HTTP client for the Truffa API.
|
|
3
|
+
Typed HTTP client for the Truffa API. Consumed by web and mobile apps. **No baked-in base URL:** pass a preconfigured HTTP layer (typically an [Axios](https://axios-http.com/) instance with `baseURL` set). Request and response shapes come from [`@ipetsadmin/contracts`](https://www.npmjs.com/package/@ipetsadmin/contracts).
|
|
4
4
|
|
|
5
5
|
## Requirements
|
|
6
6
|
|
|
7
7
|
- **Node.js** ≥ 18.18
|
|
8
|
-
- **Peer dependency:** `@ipetsadmin/contracts` (
|
|
8
|
+
- **Peer dependency:** `@ipetsadmin/contracts` **≥ 1.1.1** (auth types, `VerifyEmailRequest`, and `IApiResponse` envelopes). Use a contracts version that includes any DTO you call (e.g. `VerifyEmailRequest` for **`verifyEmail`**).
|
|
9
9
|
|
|
10
10
|
## Installation
|
|
11
11
|
|
|
@@ -15,338 +15,98 @@ pnpm add @ipetsadmin/api-client @ipetsadmin/contracts
|
|
|
15
15
|
npm install @ipetsadmin/api-client @ipetsadmin/contracts
|
|
16
16
|
```
|
|
17
17
|
|
|
18
|
-
##
|
|
18
|
+
## What ships today
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
| Export | Description |
|
|
21
|
+
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
22
|
+
| `createApiClient(options)` | Factory returning **`healthCheck`** and **`auth`** namespace |
|
|
23
|
+
| `ApiClient` / `CreateApiClientOptions` | Typed client and `{ http: HttpClient }` options |
|
|
24
|
+
| `HttpClient` | **`get`**, **`post`**, and **`patch`** (minimal surface compatible with Axios) |
|
|
25
|
+
| `HttpGet` / `HttpPost` / `HttpPatch` | Method signatures |
|
|
26
|
+
| Named helpers | Same calls as `client.*` — see [`src/endpoints/auth.ts`](./src/endpoints/auth.ts) and [`src/endpoints/health-check.ts`](./src/endpoints/health-check.ts) |
|
|
21
27
|
|
|
22
|
-
|
|
23
|
-
| -------------------------- | ----------------------------------------------------------------------- |
|
|
24
|
-
| `createApiClient(options)` | Factory that returns an object of API methods. |
|
|
25
|
-
| `ApiClient` | Type of the object returned by `createApiClient`. |
|
|
26
|
-
| `CreateApiClientOptions` | `{ http: HttpClient }`. |
|
|
27
|
-
| `HttpClient` | Minimal interface your HTTP layer must satisfy (today: **`get` only**). |
|
|
28
|
-
| `HttpGet` | Type of the `get` method. |
|
|
28
|
+
### Parity with `@ipetsadmin/api-main`
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
The API currently mounts **one public JSON surface** used by this client (see `api-main` `server.ts` / `routes/auth.routes.ts`):
|
|
31
31
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
| `GET
|
|
32
|
+
| Area | Server routes this client implements |
|
|
33
|
+
| ---------- | ------------------------------------ |
|
|
34
|
+
| **Health** | `GET /api/v1/health-check` |
|
|
35
|
+
| **Auth** | All routes under `/api/v1/auth/…` |
|
|
35
36
|
|
|
36
|
-
|
|
37
|
+
`api-main` also serves **OpenAPI** (`/api-docs`, `/api-docs.json`) when enabled; that is not wrapped here.
|
|
38
|
+
|
|
39
|
+
### Endpoints
|
|
40
|
+
|
|
41
|
+
| HTTP | Path | `createApiClient` | Named helper |
|
|
42
|
+
| ------- | ------------------------------------------------- | ---------------------------------------------- | ---------------------------------------- |
|
|
43
|
+
| `GET` | `/api/v1/health-check` | `client.healthCheck()` | `fetchHealthCheck(http)` |
|
|
44
|
+
| `POST` | `/api/v1/auth/register` | `client.auth.register(body)` | `postRegister(http, body)` |
|
|
45
|
+
| `POST` | `/api/v1/auth/login` | `client.auth.login(body)` | `postLogin(http, body)` |
|
|
46
|
+
| `GET` | `/api/v1/auth/oauth/google/start?redirectUri=...` | `client.auth.getGoogleOAuthStart(redirectUri)` | `getGoogleOAuthStart(http, redirectUri)` |
|
|
47
|
+
| `POST` | `/api/v1/auth/oauth/google/callback` | `client.auth.postGoogleOAuthCallback(body)` | `postGoogleOAuthCallback(http, body)` |
|
|
48
|
+
| `POST` | `/api/v1/auth/refresh` | `client.auth.refresh(body)` | `postRefresh(http, body)` |
|
|
49
|
+
| `POST` | `/api/v1/auth/logout` | `client.auth.logout(body)` | `postLogout(http, body)` |
|
|
50
|
+
| `PATCH` | `/api/v1/auth/verify-email` | `client.auth.verifyEmail(body)` | `patchVerifyEmail(http, body)` |
|
|
51
|
+
| `GET` | `/api/v1/auth/me` | `client.auth.me(accessToken)` | `getMe(http, accessToken)` |
|
|
52
|
+
|
|
53
|
+
Responses use **`IApiResponse<T>`** from contracts (`success`, `data`, etc.). Auth session payloads are **`AuthSessionResponse`** (`TokenPair` + `user`). **`logout`** returns **204** with no JSON body. **`verifyEmail`** success envelope matches the server (typically `data` may be empty).
|
|
37
54
|
|
|
38
55
|
### Usage example (Axios)
|
|
39
56
|
|
|
40
|
-
|
|
57
|
+
Paths are **relative to `baseURL`** (e.g. `https://api.example.com`).
|
|
41
58
|
|
|
42
59
|
```typescript
|
|
43
60
|
import axios from 'axios';
|
|
44
61
|
import { createApiClient } from '@ipetsadmin/api-client';
|
|
45
62
|
|
|
46
63
|
const http = axios.create({
|
|
47
|
-
baseURL: process.env.API_BASE_URL,
|
|
48
|
-
timeout:
|
|
64
|
+
baseURL: process.env.API_BASE_URL,
|
|
65
|
+
timeout: 30_000,
|
|
49
66
|
headers: { 'Content-Type': 'application/json' },
|
|
50
67
|
});
|
|
51
68
|
|
|
52
69
|
const api = createApiClient({ http });
|
|
53
70
|
|
|
54
71
|
const health = await api.healthCheck();
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
Axios’s `get` signature matches what this library expects: it returns a `Promise` that resolves to an object with a `data` property.
|
|
59
|
-
|
|
60
|
-
### Why a factory?
|
|
61
|
-
|
|
62
|
-
`createApiClient({ http })` keeps this package free of environment-specific configuration, supports multiple backends or tenants in one app, and makes tests trivial by injecting a mock `http` object.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Architecture overview
|
|
67
|
-
|
|
68
|
-
1. **`HttpClient`** — Abstraction over “how” HTTP is performed (Axios, `fetch` wrapper, etc.).
|
|
69
|
-
2. **`src/endpoints/*.ts`** — One module per route (or per resource): pure async functions that take `http` and return typed data.
|
|
70
|
-
3. **`createApiClient`** — Wires `http` into those functions and exposes a stable, discoverable API.
|
|
71
|
-
4. **`@ipetsadmin/contracts`** — Source of truth for DTOs shared with the server (e.g. `IApiResponse<T>`).
|
|
72
|
-
|
|
73
|
-
When the API adds a route, add an endpoint module, extend `HttpClient` if you need new verbs, and add a method on the object returned by `createApiClient`.
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Extending `HttpClient` for all HTTP verbs
|
|
78
|
-
|
|
79
|
-
Right now `HttpClient` only declares `get`. For **POST**, **PATCH**, **PUT**, and **DELETE**, extend the interface so adapters (Axios) stay type-safe and consistent.
|
|
80
|
-
|
|
81
|
-
Axios maps HTTP concepts roughly as follows:
|
|
82
|
-
|
|
83
|
-
| Concern | Axios request config field |
|
|
84
|
-
| ------------ | -------------------------------------------------------------- |
|
|
85
|
-
| URL path | First argument `url` (often built from path + **path params**) |
|
|
86
|
-
| Query string | `params` |
|
|
87
|
-
| JSON body | `data` |
|
|
88
|
-
| Headers | `headers` |
|
|
89
|
-
|
|
90
|
-
Recommended shape (mirror Axios so an `AxiosInstance` is assignable with minimal wrapping):
|
|
91
|
-
|
|
92
|
-
```typescript
|
|
93
|
-
// src/http-client.ts — extend when you add non-GET endpoints
|
|
94
|
-
|
|
95
|
-
/** Optional config aligned with Axios (params, data, headers, etc.). */
|
|
96
|
-
export type HttpRequestConfig = {
|
|
97
|
-
params?: Record<string, unknown>;
|
|
98
|
-
data?: unknown;
|
|
99
|
-
headers?: Record<string, string>;
|
|
100
|
-
};
|
|
101
|
-
|
|
102
|
-
export type HttpGet = <TResponse>(
|
|
103
|
-
url: string,
|
|
104
|
-
config?: HttpRequestConfig,
|
|
105
|
-
) => Promise<{ data: TResponse }>;
|
|
106
|
-
|
|
107
|
-
export type HttpPost = <TResponse>(
|
|
108
|
-
url: string,
|
|
109
|
-
config?: HttpRequestConfig,
|
|
110
|
-
) => Promise<{ data: TResponse }>;
|
|
111
|
-
|
|
112
|
-
export type HttpPut = HttpPost;
|
|
113
|
-
export type HttpPatch = HttpPost;
|
|
114
|
-
|
|
115
|
-
export type HttpDelete = <TResponse>(
|
|
116
|
-
url: string,
|
|
117
|
-
config?: HttpRequestConfig,
|
|
118
|
-
) => Promise<{ data: TResponse }>;
|
|
119
|
-
|
|
120
|
-
export interface HttpClient {
|
|
121
|
-
readonly get: HttpGet;
|
|
122
|
-
readonly post: HttpPost;
|
|
123
|
-
readonly put: HttpPut;
|
|
124
|
-
readonly patch: HttpPatch;
|
|
125
|
-
readonly delete: HttpDelete;
|
|
126
|
-
}
|
|
127
|
-
```
|
|
128
|
-
|
|
129
|
-
**Adapter example (Axios):** if TypeScript complains about `config` width, use a typed wrapper:
|
|
130
|
-
|
|
131
|
-
```typescript
|
|
132
|
-
import type { AxiosInstance } from 'axios';
|
|
133
|
-
import type { HttpClient, HttpRequestConfig } from '@ipetsadmin/api-client';
|
|
134
|
-
|
|
135
|
-
export function createAxiosHttpClient(instance: AxiosInstance): HttpClient {
|
|
136
|
-
return {
|
|
137
|
-
get: (url, config) => instance.get(url, config),
|
|
138
|
-
post: (url, config) => instance.post(url, config?.data, config),
|
|
139
|
-
put: (url, config) => instance.put(url, config?.data, config),
|
|
140
|
-
patch: (url, config) => instance.patch(url, config?.data, config),
|
|
141
|
-
delete: (url, config) => instance.delete(url, config),
|
|
142
|
-
};
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Note: Axios’s `post`/`put`/`patch` take `data` as the second argument and `config` as the third; the wrapper above keeps your **endpoint** code calling `http.post(url, { data, params, headers })` in one place. Adjust the wrapper to match how you prefer to thread `config`.
|
|
147
|
-
|
|
148
|
-
---
|
|
149
|
-
|
|
150
|
-
## Implementing endpoints: patterns by verb
|
|
151
|
-
|
|
152
|
-
Conventions used below:
|
|
153
|
-
|
|
154
|
-
- **Path** — string constant; combine with **path parameters** via a small helper or template.
|
|
155
|
-
- **Query** — `config.params` (Axios serializes to the query string).
|
|
156
|
-
- **Body** — `config.data` for JSON bodies.
|
|
157
|
-
- **Headers** — `config.headers` for per-request headers (auth, idempotency keys, etc.).
|
|
158
|
-
- **Types** — import request/response types from `@ipetsadmin/contracts` when they exist.
|
|
159
|
-
|
|
160
|
-
Assume:
|
|
161
|
-
|
|
162
|
-
```typescript
|
|
163
|
-
import type { IApiResponse } from '@ipetsadmin/contracts';
|
|
164
|
-
import type { HttpClient } from '../http-client';
|
|
165
|
-
```
|
|
166
|
-
|
|
167
|
-
### Path parameters
|
|
168
|
-
|
|
169
|
-
Build the URL in the endpoint (keep templates next to the constant for clarity):
|
|
170
|
-
|
|
171
|
-
```typescript
|
|
172
|
-
const USER_BY_ID_PATH = '/api/v1/users/:userId' as const;
|
|
173
|
-
|
|
174
|
-
function buildUserPath(userId: string): string {
|
|
175
|
-
return USER_BY_ID_PATH.replace(':userId', encodeURIComponent(userId));
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
// GET /api/v1/users/42
|
|
179
|
-
await http.get<IApiResponse<UserDto>>(buildUserPath('42'));
|
|
180
|
-
```
|
|
181
|
-
|
|
182
|
-
For many segments, a tiny helper avoids mistakes:
|
|
183
|
-
|
|
184
|
-
```typescript
|
|
185
|
-
function buildPath(template: string, params: Record<string, string | number>): string {
|
|
186
|
-
let path = template;
|
|
187
|
-
for (const [key, value] of Object.entries(params)) {
|
|
188
|
-
path = path.replace(`:${key}`, encodeURIComponent(String(value)));
|
|
189
|
-
}
|
|
190
|
-
return path;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// '/api/v1/orgs/:orgId/projects/:projectId'
|
|
194
|
-
buildPath('/api/v1/orgs/:orgId/projects/:projectId', {
|
|
195
|
-
orgId: 'acme',
|
|
196
|
-
projectId: 'proj-1',
|
|
197
|
-
});
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### GET — query and headers
|
|
201
|
-
|
|
202
|
-
```typescript
|
|
203
|
-
const SEARCH_PATH = '/api/v1/items' as const;
|
|
204
|
-
|
|
205
|
-
export interface ListItemsParams {
|
|
206
|
-
readonly query?: Record<string, string | number | boolean | undefined>;
|
|
207
|
-
readonly headers?: Record<string, string>;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
export async function fetchItems(
|
|
211
|
-
http: HttpClient,
|
|
212
|
-
args: ListItemsParams = {},
|
|
213
|
-
): Promise<IApiResponse<ItemSummary[]>> {
|
|
214
|
-
const { data } = await http.get<IApiResponse<ItemSummary[]>>(SEARCH_PATH, {
|
|
215
|
-
params: args.query,
|
|
216
|
-
headers: args.headers,
|
|
217
|
-
});
|
|
218
|
-
return data;
|
|
219
|
-
}
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
### POST — body, query, headers
|
|
223
|
-
|
|
224
|
-
```typescript
|
|
225
|
-
const CREATE_ITEM_PATH = '/api/v1/items' as const;
|
|
226
|
-
|
|
227
|
-
export interface CreateItemInput {
|
|
228
|
-
readonly body: CreateItemRequestDto;
|
|
229
|
-
readonly query?: Record<string, string | number | boolean | undefined>;
|
|
230
|
-
readonly headers?: Record<string, string>;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
export async function createItem(
|
|
234
|
-
http: HttpClient,
|
|
235
|
-
input: CreateItemInput,
|
|
236
|
-
): Promise<IApiResponse<ItemDto>> {
|
|
237
|
-
const { data } = await http.post<IApiResponse<ItemDto>>(CREATE_ITEM_PATH, {
|
|
238
|
-
data: input.body,
|
|
239
|
-
params: input.query,
|
|
240
|
-
headers: input.headers,
|
|
241
|
-
});
|
|
242
|
-
return data;
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
### PATCH — partial body, path id
|
|
247
|
-
|
|
248
|
-
```typescript
|
|
249
|
-
const ITEM_PATH = '/api/v1/items/:itemId' as const;
|
|
250
|
-
|
|
251
|
-
export interface UpdateItemInput {
|
|
252
|
-
readonly itemId: string;
|
|
253
|
-
readonly body: Partial<UpdateItemRequestDto>;
|
|
254
|
-
readonly headers?: Record<string, string>;
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
export async function updateItem(
|
|
258
|
-
http: HttpClient,
|
|
259
|
-
input: UpdateItemInput,
|
|
260
|
-
): Promise<IApiResponse<ItemDto>> {
|
|
261
|
-
const path = buildPath(ITEM_PATH, { itemId: input.itemId });
|
|
262
|
-
const { data } = await http.patch<IApiResponse<ItemDto>>(path, {
|
|
263
|
-
data: input.body,
|
|
264
|
-
headers: input.headers,
|
|
265
|
-
});
|
|
266
|
-
return data;
|
|
267
|
-
}
|
|
72
|
+
const session = await api.auth.login({ email: 'user@example.com', password: '********' });
|
|
73
|
+
// session — IApiResponse<AuthSessionResponse>; with Axios, the HTTP body is axiosResponse.data
|
|
268
74
|
```
|
|
269
75
|
|
|
270
|
-
|
|
76
|
+
For **`IApiResponse<AuthSessionResponse>`**, the **envelope** is the JSON body; the **`AuthSessionResponse`** is usually **`response.data.data`** (outer `data` = Axios, inner `data` = API payload), depending on typings.
|
|
271
77
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
```typescript
|
|
275
|
-
export async function replaceItem(
|
|
276
|
-
http: HttpClient,
|
|
277
|
-
input: { itemId: string; body: ReplaceItemRequestDto; headers?: Record<string, string> },
|
|
278
|
-
): Promise<IApiResponse<ItemDto>> {
|
|
279
|
-
const path = buildPath('/api/v1/items/:itemId', { itemId: input.itemId });
|
|
280
|
-
const { data } = await http.put<IApiResponse<ItemDto>>(path, {
|
|
281
|
-
data: input.body,
|
|
282
|
-
headers: input.headers,
|
|
283
|
-
});
|
|
284
|
-
return data;
|
|
285
|
-
}
|
|
286
|
-
```
|
|
78
|
+
### OAuth (mobile / web)
|
|
287
79
|
|
|
288
|
-
|
|
80
|
+
1. Call **`getGoogleOAuthStart`** with the same **`redirectUri`** you registered in Auth0 and in the API’s `OAUTH_ALLOWED_REDIRECT_URIS`.
|
|
81
|
+
2. Open **`authorizationUrl`** in a browser / `ASWebAuthenticationSession`.
|
|
82
|
+
3. After redirect, send **`code`**, **`state`**, and **`redirectUri`** with **`postGoogleOAuthCallback`**.
|
|
289
83
|
|
|
290
|
-
|
|
84
|
+
### Email verification
|
|
291
85
|
|
|
292
|
-
|
|
293
|
-
export async function deleteItem(
|
|
294
|
-
http: HttpClient,
|
|
295
|
-
itemId: string,
|
|
296
|
-
headers?: Record<string, string>,
|
|
297
|
-
): Promise<IApiResponse<void>> {
|
|
298
|
-
const path = buildPath('/api/v1/items/:itemId', { itemId });
|
|
299
|
-
const { data } = await http.delete<IApiResponse<void>>(path, { headers });
|
|
300
|
-
return data;
|
|
301
|
-
}
|
|
302
|
-
```
|
|
86
|
+
Call **`api.auth.verifyEmail({ token })`** (or **`patchVerifyEmail`**) with the one-time token from the verification link your backend emails. Shapes: **`VerifyEmailRequest`** from `@ipetsadmin/contracts`.
|
|
303
87
|
|
|
304
|
-
|
|
88
|
+
### Why a factory?
|
|
305
89
|
|
|
306
|
-
|
|
307
|
-
await http.delete<IApiResponse<void>>(path, {
|
|
308
|
-
data: { reason: 'user_request' },
|
|
309
|
-
headers: { 'Content-Type': 'application/json' },
|
|
310
|
-
});
|
|
311
|
-
```
|
|
90
|
+
`createApiClient({ http })` keeps env and transport out of this package, supports multiple backends in one app, and makes tests easy with a mock `http` object.
|
|
312
91
|
|
|
313
92
|
---
|
|
314
93
|
|
|
315
|
-
##
|
|
94
|
+
## Architecture
|
|
316
95
|
|
|
317
|
-
1.
|
|
318
|
-
2.
|
|
319
|
-
3.
|
|
96
|
+
1. **`HttpClient`** — abstraction over **`get` / `post` / `patch`** (`{ data: T }` response shape, Axios-compatible).
|
|
97
|
+
2. **`src/endpoints/*.ts`** — thin functions: `(http, …args) => Promise<…>`.
|
|
98
|
+
3. **`createApiClient`** — wires `http` into those endpoints.
|
|
99
|
+
4. **`@ipetsadmin/contracts`** — DTOs (`RegisterRequest`, `AuthSessionResponse`, `VerifyEmailRequest`, …).
|
|
320
100
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
// src/create-api-client.ts
|
|
325
|
-
import { createItem } from './endpoints/create-item';
|
|
326
|
-
import { fetchItems } from './endpoints/list-items';
|
|
327
|
-
import { fetchHealthCheck } from './endpoints/health-check';
|
|
328
|
-
import type { HttpClient } from './http-client';
|
|
329
|
-
|
|
330
|
-
export function createApiClient(options: { http: HttpClient }) {
|
|
331
|
-
const { http } = options;
|
|
332
|
-
|
|
333
|
-
return {
|
|
334
|
-
healthCheck: () => fetchHealthCheck(http),
|
|
335
|
-
listItems: (params?: ListItemsParams) => fetchItems(http, params),
|
|
336
|
-
createItem: (input: CreateItemInput) => createItem(http, input),
|
|
337
|
-
};
|
|
338
|
-
}
|
|
339
|
-
```
|
|
101
|
+
### Extending further
|
|
340
102
|
|
|
341
|
-
|
|
103
|
+
Add methods on **`HttpClient`** in `src/http-client.ts`, then new endpoint modules. For query params, headers, and `Authorization`, align with your adapter (Axios passes a `config` object to **`get`**, **`post`**, and **`patch`**; **`getMe`** already sets `Authorization: Bearer` for the access token argument).
|
|
342
104
|
|
|
343
105
|
---
|
|
344
106
|
|
|
345
107
|
## Testing
|
|
346
108
|
|
|
347
|
-
Inject a fake
|
|
348
|
-
|
|
349
|
-
**With the current `HttpClient` (only `get`):**
|
|
109
|
+
Inject a fake **`HttpClient`** with **`get`**, **`post`**, and **`patch`** mocks and assert URLs and payloads.
|
|
350
110
|
|
|
351
111
|
```typescript
|
|
352
112
|
import type { HttpClient } from '@ipetsadmin/api-client';
|
|
@@ -354,34 +114,33 @@ import { createApiClient } from '@ipetsadmin/api-client';
|
|
|
354
114
|
|
|
355
115
|
const http: HttpClient = {
|
|
356
116
|
get: jest.fn().mockResolvedValue({ data: { success: true, data: {} } }),
|
|
117
|
+
post: jest.fn().mockResolvedValue({ data: { success: true, data: {} } }),
|
|
118
|
+
patch: jest.fn().mockResolvedValue({ data: { success: true } }),
|
|
357
119
|
};
|
|
358
120
|
|
|
359
121
|
const api = createApiClient({ http });
|
|
360
122
|
await api.healthCheck();
|
|
361
|
-
|
|
362
123
|
expect(http.get).toHaveBeenCalledWith('/api/v1/health-check', undefined);
|
|
363
124
|
```
|
|
364
125
|
|
|
365
|
-
**After you extend `HttpClient` with `post` / `put` / `patch` / `delete`,** add matching mocks (e.g. `post: jest.fn()`) so the object satisfies the full interface.
|
|
366
|
-
|
|
367
126
|
---
|
|
368
127
|
|
|
369
128
|
## Development (this repository)
|
|
370
129
|
|
|
371
|
-
| Script | Purpose
|
|
372
|
-
| ------------------------- |
|
|
373
|
-
| `pnpm run build` |
|
|
374
|
-
| `pnpm run typecheck` | `tsc --noEmit`
|
|
375
|
-
| `pnpm run lint` | ESLint
|
|
376
|
-
| `pnpm run validate` | typecheck + lint + Prettier check
|
|
377
|
-
| `pnpm run prepublishOnly` |
|
|
130
|
+
| Script | Purpose |
|
|
131
|
+
| ------------------------- | ------------------------------------ |
|
|
132
|
+
| `pnpm run build` | `tsup` → `dist/` (CJS, ESM, `.d.ts`) |
|
|
133
|
+
| `pnpm run typecheck` | `tsc --noEmit` |
|
|
134
|
+
| `pnpm run lint` | ESLint |
|
|
135
|
+
| `pnpm run validate` | typecheck + lint + Prettier check |
|
|
136
|
+
| `pnpm run prepublishOnly` | validate + build before publish |
|
|
378
137
|
|
|
379
138
|
---
|
|
380
139
|
|
|
381
|
-
##
|
|
140
|
+
## Changelog
|
|
141
|
+
|
|
142
|
+
See [CHANGELOG.md](./CHANGELOG.md).
|
|
382
143
|
|
|
383
|
-
|
|
384
|
-
- **Next:** Extend `HttpClient` with `post` / `put` / `patch` / `delete` and optional `HttpRequestConfig`, then add endpoint modules that use **path helpers**, **`params`**, **`data`**, and **`headers`** as shown above.
|
|
385
|
-
- **Types:** Prefer `@ipetsadmin/contracts` for DTOs and `IApiResponse<T>` for envelope responses.
|
|
144
|
+
## License
|
|
386
145
|
|
|
387
|
-
|
|
146
|
+
MIT — see [LICENSE](./LICENSE).
|
package/dist/index.d.mts
CHANGED
|
@@ -1,20 +1,47 @@
|
|
|
1
|
-
import { IApiResponse } from '@ipetsadmin/contracts';
|
|
1
|
+
import { RegisterRequest, IApiResponse, AuthSessionResponse, LoginRequest, OAuthGoogleStartResponse, OAuthGoogleCallbackRequest, RefreshRequest, LogoutRequest, VerifyEmailRequest, AuthUserResponse, HealthCheck } from '@ipetsadmin/contracts';
|
|
2
2
|
|
|
3
3
|
type HttpGet = <TResponse>(url: string, config?: unknown) => Promise<{
|
|
4
4
|
data: TResponse;
|
|
5
5
|
}>;
|
|
6
|
+
type HttpPost = <TResponse, TBody = unknown>(url: string, body?: TBody, config?: unknown) => Promise<{
|
|
7
|
+
data: TResponse;
|
|
8
|
+
}>;
|
|
9
|
+
type HttpPatch = <TResponse, TBody = unknown>(url: string, body?: TBody, config?: unknown) => Promise<{
|
|
10
|
+
data: TResponse;
|
|
11
|
+
}>;
|
|
6
12
|
interface HttpClient {
|
|
7
13
|
readonly get: HttpGet;
|
|
14
|
+
readonly post: HttpPost;
|
|
15
|
+
readonly patch: HttpPatch;
|
|
8
16
|
}
|
|
9
17
|
|
|
10
|
-
declare function
|
|
18
|
+
declare function postRegister(http: HttpClient, body: RegisterRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
19
|
+
declare function postLogin(http: HttpClient, body: LoginRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
20
|
+
declare function getGoogleOAuthStart(http: HttpClient, redirectUri: string): Promise<IApiResponse<OAuthGoogleStartResponse>>;
|
|
21
|
+
declare function postGoogleOAuthCallback(http: HttpClient, body: OAuthGoogleCallbackRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
22
|
+
declare function postRefresh(http: HttpClient, body: RefreshRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
23
|
+
declare function postLogout(http: HttpClient, body: LogoutRequest): Promise<void>;
|
|
24
|
+
declare function getMe(http: HttpClient, accessToken: string): Promise<IApiResponse<AuthUserResponse>>;
|
|
25
|
+
declare function patchVerifyEmail(http: HttpClient, body: VerifyEmailRequest): Promise<IApiResponse<void>>;
|
|
26
|
+
|
|
27
|
+
declare function fetchHealthCheck(http: HttpClient): Promise<IApiResponse<HealthCheck>>;
|
|
11
28
|
|
|
12
29
|
interface CreateApiClientOptions {
|
|
13
30
|
readonly http: HttpClient;
|
|
14
31
|
}
|
|
15
32
|
interface ApiClient {
|
|
16
33
|
readonly healthCheck: () => ReturnType<typeof fetchHealthCheck>;
|
|
34
|
+
readonly auth: {
|
|
35
|
+
readonly register: (body: Parameters<typeof postRegister>[1]) => ReturnType<typeof postRegister>;
|
|
36
|
+
readonly login: (body: Parameters<typeof postLogin>[1]) => ReturnType<typeof postLogin>;
|
|
37
|
+
readonly getGoogleOAuthStart: (redirectUri: string) => ReturnType<typeof getGoogleOAuthStart>;
|
|
38
|
+
readonly postGoogleOAuthCallback: (body: Parameters<typeof postGoogleOAuthCallback>[1]) => ReturnType<typeof postGoogleOAuthCallback>;
|
|
39
|
+
readonly refresh: (body: Parameters<typeof postRefresh>[1]) => ReturnType<typeof postRefresh>;
|
|
40
|
+
readonly logout: (body: Parameters<typeof postLogout>[1]) => ReturnType<typeof postLogout>;
|
|
41
|
+
readonly verifyEmail: (body: Parameters<typeof patchVerifyEmail>[1]) => ReturnType<typeof patchVerifyEmail>;
|
|
42
|
+
readonly me: (accessToken: string) => ReturnType<typeof getMe>;
|
|
43
|
+
};
|
|
17
44
|
}
|
|
18
45
|
declare function createApiClient(options: CreateApiClientOptions): ApiClient;
|
|
19
46
|
|
|
20
|
-
export { type ApiClient, type CreateApiClientOptions, type HttpClient, type HttpGet, createApiClient };
|
|
47
|
+
export { type ApiClient, type CreateApiClientOptions, type HttpClient, type HttpGet, type HttpPatch, type HttpPost, createApiClient, getGoogleOAuthStart, getMe, patchVerifyEmail, postGoogleOAuthCallback, postLogin, postLogout, postRefresh, postRegister };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,20 +1,47 @@
|
|
|
1
|
-
import { IApiResponse } from '@ipetsadmin/contracts';
|
|
1
|
+
import { RegisterRequest, IApiResponse, AuthSessionResponse, LoginRequest, OAuthGoogleStartResponse, OAuthGoogleCallbackRequest, RefreshRequest, LogoutRequest, VerifyEmailRequest, AuthUserResponse, HealthCheck } from '@ipetsadmin/contracts';
|
|
2
2
|
|
|
3
3
|
type HttpGet = <TResponse>(url: string, config?: unknown) => Promise<{
|
|
4
4
|
data: TResponse;
|
|
5
5
|
}>;
|
|
6
|
+
type HttpPost = <TResponse, TBody = unknown>(url: string, body?: TBody, config?: unknown) => Promise<{
|
|
7
|
+
data: TResponse;
|
|
8
|
+
}>;
|
|
9
|
+
type HttpPatch = <TResponse, TBody = unknown>(url: string, body?: TBody, config?: unknown) => Promise<{
|
|
10
|
+
data: TResponse;
|
|
11
|
+
}>;
|
|
6
12
|
interface HttpClient {
|
|
7
13
|
readonly get: HttpGet;
|
|
14
|
+
readonly post: HttpPost;
|
|
15
|
+
readonly patch: HttpPatch;
|
|
8
16
|
}
|
|
9
17
|
|
|
10
|
-
declare function
|
|
18
|
+
declare function postRegister(http: HttpClient, body: RegisterRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
19
|
+
declare function postLogin(http: HttpClient, body: LoginRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
20
|
+
declare function getGoogleOAuthStart(http: HttpClient, redirectUri: string): Promise<IApiResponse<OAuthGoogleStartResponse>>;
|
|
21
|
+
declare function postGoogleOAuthCallback(http: HttpClient, body: OAuthGoogleCallbackRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
22
|
+
declare function postRefresh(http: HttpClient, body: RefreshRequest): Promise<IApiResponse<AuthSessionResponse>>;
|
|
23
|
+
declare function postLogout(http: HttpClient, body: LogoutRequest): Promise<void>;
|
|
24
|
+
declare function getMe(http: HttpClient, accessToken: string): Promise<IApiResponse<AuthUserResponse>>;
|
|
25
|
+
declare function patchVerifyEmail(http: HttpClient, body: VerifyEmailRequest): Promise<IApiResponse<void>>;
|
|
26
|
+
|
|
27
|
+
declare function fetchHealthCheck(http: HttpClient): Promise<IApiResponse<HealthCheck>>;
|
|
11
28
|
|
|
12
29
|
interface CreateApiClientOptions {
|
|
13
30
|
readonly http: HttpClient;
|
|
14
31
|
}
|
|
15
32
|
interface ApiClient {
|
|
16
33
|
readonly healthCheck: () => ReturnType<typeof fetchHealthCheck>;
|
|
34
|
+
readonly auth: {
|
|
35
|
+
readonly register: (body: Parameters<typeof postRegister>[1]) => ReturnType<typeof postRegister>;
|
|
36
|
+
readonly login: (body: Parameters<typeof postLogin>[1]) => ReturnType<typeof postLogin>;
|
|
37
|
+
readonly getGoogleOAuthStart: (redirectUri: string) => ReturnType<typeof getGoogleOAuthStart>;
|
|
38
|
+
readonly postGoogleOAuthCallback: (body: Parameters<typeof postGoogleOAuthCallback>[1]) => ReturnType<typeof postGoogleOAuthCallback>;
|
|
39
|
+
readonly refresh: (body: Parameters<typeof postRefresh>[1]) => ReturnType<typeof postRefresh>;
|
|
40
|
+
readonly logout: (body: Parameters<typeof postLogout>[1]) => ReturnType<typeof postLogout>;
|
|
41
|
+
readonly verifyEmail: (body: Parameters<typeof patchVerifyEmail>[1]) => ReturnType<typeof patchVerifyEmail>;
|
|
42
|
+
readonly me: (accessToken: string) => ReturnType<typeof getMe>;
|
|
43
|
+
};
|
|
17
44
|
}
|
|
18
45
|
declare function createApiClient(options: CreateApiClientOptions): ApiClient;
|
|
19
46
|
|
|
20
|
-
export { type ApiClient, type CreateApiClientOptions, type HttpClient, type HttpGet, createApiClient };
|
|
47
|
+
export { type ApiClient, type CreateApiClientOptions, type HttpClient, type HttpGet, type HttpPatch, type HttpPost, createApiClient, getGoogleOAuthStart, getMe, patchVerifyEmail, postGoogleOAuthCallback, postLogin, postLogout, postRefresh, postRegister };
|
package/dist/index.js
CHANGED
|
@@ -1,20 +1,92 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
// src/endpoints/auth.ts
|
|
4
|
+
var AUTH_BASE = "/api/v1/auth";
|
|
5
|
+
async function postRegister(http, body) {
|
|
6
|
+
const { data } = await http.post(
|
|
7
|
+
`${AUTH_BASE}/register`,
|
|
8
|
+
body
|
|
9
|
+
);
|
|
10
|
+
return data;
|
|
11
|
+
}
|
|
12
|
+
async function postLogin(http, body) {
|
|
13
|
+
const { data } = await http.post(
|
|
14
|
+
`${AUTH_BASE}/login`,
|
|
15
|
+
body
|
|
16
|
+
);
|
|
17
|
+
return data;
|
|
18
|
+
}
|
|
19
|
+
async function getGoogleOAuthStart(http, redirectUri) {
|
|
20
|
+
const q = new URLSearchParams({ redirectUri });
|
|
21
|
+
const { data } = await http.get(
|
|
22
|
+
`${AUTH_BASE}/oauth/google/start?${q.toString()}`
|
|
23
|
+
);
|
|
24
|
+
return data;
|
|
25
|
+
}
|
|
26
|
+
async function postGoogleOAuthCallback(http, body) {
|
|
27
|
+
const { data } = await http.post(
|
|
28
|
+
`${AUTH_BASE}/oauth/google/callback`,
|
|
29
|
+
body
|
|
30
|
+
);
|
|
31
|
+
return data;
|
|
32
|
+
}
|
|
33
|
+
async function postRefresh(http, body) {
|
|
34
|
+
const { data } = await http.post(
|
|
35
|
+
`${AUTH_BASE}/refresh`,
|
|
36
|
+
body
|
|
37
|
+
);
|
|
38
|
+
return data;
|
|
39
|
+
}
|
|
40
|
+
async function postLogout(http, body) {
|
|
41
|
+
await http.post(`${AUTH_BASE}/logout`, body);
|
|
42
|
+
}
|
|
43
|
+
async function getMe(http, accessToken) {
|
|
44
|
+
const { data } = await http.get(`${AUTH_BASE}/me`, {
|
|
45
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
46
|
+
});
|
|
47
|
+
return data;
|
|
48
|
+
}
|
|
49
|
+
async function patchVerifyEmail(http, body) {
|
|
50
|
+
const { data } = await http.patch(
|
|
51
|
+
`${AUTH_BASE}/verify-email`,
|
|
52
|
+
body
|
|
53
|
+
);
|
|
54
|
+
return data;
|
|
55
|
+
}
|
|
56
|
+
|
|
3
57
|
// src/endpoints/health-check.ts
|
|
4
58
|
var HEALTH_CHECK_PATH = "/api/v1/health-check";
|
|
5
59
|
async function fetchHealthCheck(http) {
|
|
6
|
-
const { data } = await http.get(HEALTH_CHECK_PATH);
|
|
7
|
-
return
|
|
60
|
+
const { data: body } = await http.get(HEALTH_CHECK_PATH);
|
|
61
|
+
return body;
|
|
8
62
|
}
|
|
9
63
|
|
|
10
64
|
// src/create-api-client.ts
|
|
11
65
|
function createApiClient(options) {
|
|
12
66
|
const { http } = options;
|
|
13
67
|
return {
|
|
14
|
-
healthCheck: () => fetchHealthCheck(http)
|
|
68
|
+
healthCheck: () => fetchHealthCheck(http),
|
|
69
|
+
auth: {
|
|
70
|
+
register: (body) => postRegister(http, body),
|
|
71
|
+
login: (body) => postLogin(http, body),
|
|
72
|
+
getGoogleOAuthStart: (redirectUri) => getGoogleOAuthStart(http, redirectUri),
|
|
73
|
+
postGoogleOAuthCallback: (body) => postGoogleOAuthCallback(http, body),
|
|
74
|
+
refresh: (body) => postRefresh(http, body),
|
|
75
|
+
logout: (body) => postLogout(http, body),
|
|
76
|
+
verifyEmail: (body) => patchVerifyEmail(http, body),
|
|
77
|
+
me: (accessToken) => getMe(http, accessToken)
|
|
78
|
+
}
|
|
15
79
|
};
|
|
16
80
|
}
|
|
17
81
|
|
|
18
82
|
exports.createApiClient = createApiClient;
|
|
83
|
+
exports.getGoogleOAuthStart = getGoogleOAuthStart;
|
|
84
|
+
exports.getMe = getMe;
|
|
85
|
+
exports.patchVerifyEmail = patchVerifyEmail;
|
|
86
|
+
exports.postGoogleOAuthCallback = postGoogleOAuthCallback;
|
|
87
|
+
exports.postLogin = postLogin;
|
|
88
|
+
exports.postLogout = postLogout;
|
|
89
|
+
exports.postRefresh = postRefresh;
|
|
90
|
+
exports.postRegister = postRegister;
|
|
19
91
|
//# sourceMappingURL=index.js.map
|
|
20
92
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/endpoints/health-check.ts","../src/create-api-client.ts"],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"sources":["../src/endpoints/auth.ts","../src/endpoints/health-check.ts","../src/create-api-client.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import type {\n AuthSessionResponse,\n AuthUserResponse,\n IApiResponse,\n LoginRequest,\n LogoutRequest,\n OAuthGoogleCallbackRequest,\n OAuthGoogleStartResponse,\n RefreshRequest,\n RegisterRequest,\n VerifyEmailRequest,\n} from '@ipetsadmin/contracts';\n\nimport type { HttpClient } from '../http-client';\n\nconst AUTH_BASE = '/api/v1/auth' as const;\n\n/**\n * POST /api/v1/auth/register\n */\nexport async function postRegister(\n http: HttpClient,\n body: RegisterRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, RegisterRequest>(\n `${AUTH_BASE}/register`,\n body,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/login\n */\nexport async function postLogin(\n http: HttpClient,\n body: LoginRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, LoginRequest>(\n `${AUTH_BASE}/login`,\n body,\n );\n return data;\n}\n\n/**\n * GET /api/v1/auth/oauth/google/start?redirectUri=...\n */\nexport async function getGoogleOAuthStart(\n http: HttpClient,\n redirectUri: string,\n): Promise<IApiResponse<OAuthGoogleStartResponse>> {\n const q = new URLSearchParams({ redirectUri });\n const { data } = await http.get<IApiResponse<OAuthGoogleStartResponse>>(\n `${AUTH_BASE}/oauth/google/start?${q.toString()}`,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/oauth/google/callback\n */\nexport async function postGoogleOAuthCallback(\n http: HttpClient,\n body: OAuthGoogleCallbackRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, OAuthGoogleCallbackRequest>(\n `${AUTH_BASE}/oauth/google/callback`,\n body,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/refresh\n */\nexport async function postRefresh(\n http: HttpClient,\n body: RefreshRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, RefreshRequest>(\n `${AUTH_BASE}/refresh`,\n body,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/logout — 204 No Content (no JSON body).\n */\nexport async function postLogout(http: HttpClient, body: LogoutRequest): Promise<void> {\n await http.post<undefined, LogoutRequest>(`${AUTH_BASE}/logout`, body);\n}\n\n/**\n * GET /api/v1/auth/me — requires `Authorization: Bearer <accessToken>`.\n */\nexport async function getMe(\n http: HttpClient,\n accessToken: string,\n): Promise<IApiResponse<AuthUserResponse>> {\n const { data } = await http.get<IApiResponse<AuthUserResponse>>(`${AUTH_BASE}/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n return data;\n}\n\n/**\n * PATCH /api/v1/auth/verify-email\n */\nexport async function patchVerifyEmail(\n http: HttpClient,\n body: VerifyEmailRequest,\n): Promise<IApiResponse<void>> {\n const { data } = await http.patch<IApiResponse<void>, VerifyEmailRequest>(\n `${AUTH_BASE}/verify-email`,\n body,\n );\n return data;\n}\n","import type { IApiResponse, HealthCheck } from '@ipetsadmin/contracts';\nimport type { HttpClient } from '../http-client';\n\n/** Same path as `/api/${v1}/health-check` on the server when `v1` is the string `'v1'`. */\nconst HEALTH_CHECK_PATH = '/api/v1/health-check' as const;\n\n/**\n * GET /api/v1/health-check — server liveness.\n *\n * Returns the full JSON the server sends (`IApiResponse<HealthCheck>`).\n *\n * **Why not `data.data` here?** Adapters like Axios wrap the HTTP body in a property also\n * called `data`. That outer `data` is the entire `res.json(...)` object. The inner\n * `IApiResponse.data` is the `HealthCheck` payload — use `.data` on the **returned** value,\n * e.g. `(await fetchHealthCheck(http)).data`.\n */\nexport async function fetchHealthCheck(http: HttpClient): Promise<IApiResponse<HealthCheck>> {\n const { data: body } = await http.get<IApiResponse<HealthCheck>>(HEALTH_CHECK_PATH);\n\n return body;\n}\n","import {\n getGoogleOAuthStart,\n getMe,\n patchVerifyEmail,\n postGoogleOAuthCallback,\n postLogin,\n postLogout,\n postRefresh,\n postRegister,\n} from './endpoints/auth';\nimport { fetchHealthCheck } from './endpoints/health-check';\nimport type { HttpClient } from './http-client';\n\nexport interface CreateApiClientOptions {\n /**\n * Preconfigured HTTP client (e.g. Axios instance with `baseURL` set).\n * Paths in this library are relative to that base (e.g. `/api/v1/...`).\n * Both `get` and `post` are required for auth flows.\n */\n readonly http: HttpClient;\n}\n\nexport interface ApiClient {\n readonly healthCheck: () => ReturnType<typeof fetchHealthCheck>;\n readonly auth: {\n readonly register: (\n body: Parameters<typeof postRegister>[1],\n ) => ReturnType<typeof postRegister>;\n readonly login: (body: Parameters<typeof postLogin>[1]) => ReturnType<typeof postLogin>;\n readonly getGoogleOAuthStart: (redirectUri: string) => ReturnType<typeof getGoogleOAuthStart>;\n readonly postGoogleOAuthCallback: (\n body: Parameters<typeof postGoogleOAuthCallback>[1],\n ) => ReturnType<typeof postGoogleOAuthCallback>;\n readonly refresh: (body: Parameters<typeof postRefresh>[1]) => ReturnType<typeof postRefresh>;\n readonly logout: (body: Parameters<typeof postLogout>[1]) => ReturnType<typeof postLogout>;\n readonly verifyEmail: (\n body: Parameters<typeof patchVerifyEmail>[1],\n ) => ReturnType<typeof patchVerifyEmail>;\n readonly me: (accessToken: string) => ReturnType<typeof getMe>;\n };\n}\n\n/**\n * Creates a typed API client backed by the provided HTTP implementation.\n */\nexport function createApiClient(options: CreateApiClientOptions): ApiClient {\n const { http } = options;\n\n return {\n healthCheck: () => fetchHealthCheck(http),\n auth: {\n register: (body) => postRegister(http, body),\n login: (body) => postLogin(http, body),\n getGoogleOAuthStart: (redirectUri) => getGoogleOAuthStart(http, redirectUri),\n postGoogleOAuthCallback: (body) => postGoogleOAuthCallback(http, body),\n refresh: (body) => postRefresh(http, body),\n logout: (body) => postLogout(http, body),\n verifyEmail: (body) => patchVerifyEmail(http, body),\n me: (accessToken) => getMe(http, accessToken),\n },\n };\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,82 @@
|
|
|
1
|
+
// src/endpoints/auth.ts
|
|
2
|
+
var AUTH_BASE = "/api/v1/auth";
|
|
3
|
+
async function postRegister(http, body) {
|
|
4
|
+
const { data } = await http.post(
|
|
5
|
+
`${AUTH_BASE}/register`,
|
|
6
|
+
body
|
|
7
|
+
);
|
|
8
|
+
return data;
|
|
9
|
+
}
|
|
10
|
+
async function postLogin(http, body) {
|
|
11
|
+
const { data } = await http.post(
|
|
12
|
+
`${AUTH_BASE}/login`,
|
|
13
|
+
body
|
|
14
|
+
);
|
|
15
|
+
return data;
|
|
16
|
+
}
|
|
17
|
+
async function getGoogleOAuthStart(http, redirectUri) {
|
|
18
|
+
const q = new URLSearchParams({ redirectUri });
|
|
19
|
+
const { data } = await http.get(
|
|
20
|
+
`${AUTH_BASE}/oauth/google/start?${q.toString()}`
|
|
21
|
+
);
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
async function postGoogleOAuthCallback(http, body) {
|
|
25
|
+
const { data } = await http.post(
|
|
26
|
+
`${AUTH_BASE}/oauth/google/callback`,
|
|
27
|
+
body
|
|
28
|
+
);
|
|
29
|
+
return data;
|
|
30
|
+
}
|
|
31
|
+
async function postRefresh(http, body) {
|
|
32
|
+
const { data } = await http.post(
|
|
33
|
+
`${AUTH_BASE}/refresh`,
|
|
34
|
+
body
|
|
35
|
+
);
|
|
36
|
+
return data;
|
|
37
|
+
}
|
|
38
|
+
async function postLogout(http, body) {
|
|
39
|
+
await http.post(`${AUTH_BASE}/logout`, body);
|
|
40
|
+
}
|
|
41
|
+
async function getMe(http, accessToken) {
|
|
42
|
+
const { data } = await http.get(`${AUTH_BASE}/me`, {
|
|
43
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
44
|
+
});
|
|
45
|
+
return data;
|
|
46
|
+
}
|
|
47
|
+
async function patchVerifyEmail(http, body) {
|
|
48
|
+
const { data } = await http.patch(
|
|
49
|
+
`${AUTH_BASE}/verify-email`,
|
|
50
|
+
body
|
|
51
|
+
);
|
|
52
|
+
return data;
|
|
53
|
+
}
|
|
54
|
+
|
|
1
55
|
// src/endpoints/health-check.ts
|
|
2
56
|
var HEALTH_CHECK_PATH = "/api/v1/health-check";
|
|
3
57
|
async function fetchHealthCheck(http) {
|
|
4
|
-
const { data } = await http.get(HEALTH_CHECK_PATH);
|
|
5
|
-
return
|
|
58
|
+
const { data: body } = await http.get(HEALTH_CHECK_PATH);
|
|
59
|
+
return body;
|
|
6
60
|
}
|
|
7
61
|
|
|
8
62
|
// src/create-api-client.ts
|
|
9
63
|
function createApiClient(options) {
|
|
10
64
|
const { http } = options;
|
|
11
65
|
return {
|
|
12
|
-
healthCheck: () => fetchHealthCheck(http)
|
|
66
|
+
healthCheck: () => fetchHealthCheck(http),
|
|
67
|
+
auth: {
|
|
68
|
+
register: (body) => postRegister(http, body),
|
|
69
|
+
login: (body) => postLogin(http, body),
|
|
70
|
+
getGoogleOAuthStart: (redirectUri) => getGoogleOAuthStart(http, redirectUri),
|
|
71
|
+
postGoogleOAuthCallback: (body) => postGoogleOAuthCallback(http, body),
|
|
72
|
+
refresh: (body) => postRefresh(http, body),
|
|
73
|
+
logout: (body) => postLogout(http, body),
|
|
74
|
+
verifyEmail: (body) => patchVerifyEmail(http, body),
|
|
75
|
+
me: (accessToken) => getMe(http, accessToken)
|
|
76
|
+
}
|
|
13
77
|
};
|
|
14
78
|
}
|
|
15
79
|
|
|
16
|
-
export { createApiClient };
|
|
80
|
+
export { createApiClient, getGoogleOAuthStart, getMe, patchVerifyEmail, postGoogleOAuthCallback, postLogin, postLogout, postRefresh, postRegister };
|
|
17
81
|
//# sourceMappingURL=index.mjs.map
|
|
18
82
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/endpoints/health-check.ts","../src/create-api-client.ts"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../src/endpoints/auth.ts","../src/endpoints/health-check.ts","../src/create-api-client.ts"],"names":[],"mappings":"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","file":"index.mjs","sourcesContent":["import type {\n AuthSessionResponse,\n AuthUserResponse,\n IApiResponse,\n LoginRequest,\n LogoutRequest,\n OAuthGoogleCallbackRequest,\n OAuthGoogleStartResponse,\n RefreshRequest,\n RegisterRequest,\n VerifyEmailRequest,\n} from '@ipetsadmin/contracts';\n\nimport type { HttpClient } from '../http-client';\n\nconst AUTH_BASE = '/api/v1/auth' as const;\n\n/**\n * POST /api/v1/auth/register\n */\nexport async function postRegister(\n http: HttpClient,\n body: RegisterRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, RegisterRequest>(\n `${AUTH_BASE}/register`,\n body,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/login\n */\nexport async function postLogin(\n http: HttpClient,\n body: LoginRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, LoginRequest>(\n `${AUTH_BASE}/login`,\n body,\n );\n return data;\n}\n\n/**\n * GET /api/v1/auth/oauth/google/start?redirectUri=...\n */\nexport async function getGoogleOAuthStart(\n http: HttpClient,\n redirectUri: string,\n): Promise<IApiResponse<OAuthGoogleStartResponse>> {\n const q = new URLSearchParams({ redirectUri });\n const { data } = await http.get<IApiResponse<OAuthGoogleStartResponse>>(\n `${AUTH_BASE}/oauth/google/start?${q.toString()}`,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/oauth/google/callback\n */\nexport async function postGoogleOAuthCallback(\n http: HttpClient,\n body: OAuthGoogleCallbackRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, OAuthGoogleCallbackRequest>(\n `${AUTH_BASE}/oauth/google/callback`,\n body,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/refresh\n */\nexport async function postRefresh(\n http: HttpClient,\n body: RefreshRequest,\n): Promise<IApiResponse<AuthSessionResponse>> {\n const { data } = await http.post<IApiResponse<AuthSessionResponse>, RefreshRequest>(\n `${AUTH_BASE}/refresh`,\n body,\n );\n return data;\n}\n\n/**\n * POST /api/v1/auth/logout — 204 No Content (no JSON body).\n */\nexport async function postLogout(http: HttpClient, body: LogoutRequest): Promise<void> {\n await http.post<undefined, LogoutRequest>(`${AUTH_BASE}/logout`, body);\n}\n\n/**\n * GET /api/v1/auth/me — requires `Authorization: Bearer <accessToken>`.\n */\nexport async function getMe(\n http: HttpClient,\n accessToken: string,\n): Promise<IApiResponse<AuthUserResponse>> {\n const { data } = await http.get<IApiResponse<AuthUserResponse>>(`${AUTH_BASE}/me`, {\n headers: { Authorization: `Bearer ${accessToken}` },\n });\n return data;\n}\n\n/**\n * PATCH /api/v1/auth/verify-email\n */\nexport async function patchVerifyEmail(\n http: HttpClient,\n body: VerifyEmailRequest,\n): Promise<IApiResponse<void>> {\n const { data } = await http.patch<IApiResponse<void>, VerifyEmailRequest>(\n `${AUTH_BASE}/verify-email`,\n body,\n );\n return data;\n}\n","import type { IApiResponse, HealthCheck } from '@ipetsadmin/contracts';\nimport type { HttpClient } from '../http-client';\n\n/** Same path as `/api/${v1}/health-check` on the server when `v1` is the string `'v1'`. */\nconst HEALTH_CHECK_PATH = '/api/v1/health-check' as const;\n\n/**\n * GET /api/v1/health-check — server liveness.\n *\n * Returns the full JSON the server sends (`IApiResponse<HealthCheck>`).\n *\n * **Why not `data.data` here?** Adapters like Axios wrap the HTTP body in a property also\n * called `data`. That outer `data` is the entire `res.json(...)` object. The inner\n * `IApiResponse.data` is the `HealthCheck` payload — use `.data` on the **returned** value,\n * e.g. `(await fetchHealthCheck(http)).data`.\n */\nexport async function fetchHealthCheck(http: HttpClient): Promise<IApiResponse<HealthCheck>> {\n const { data: body } = await http.get<IApiResponse<HealthCheck>>(HEALTH_CHECK_PATH);\n\n return body;\n}\n","import {\n getGoogleOAuthStart,\n getMe,\n patchVerifyEmail,\n postGoogleOAuthCallback,\n postLogin,\n postLogout,\n postRefresh,\n postRegister,\n} from './endpoints/auth';\nimport { fetchHealthCheck } from './endpoints/health-check';\nimport type { HttpClient } from './http-client';\n\nexport interface CreateApiClientOptions {\n /**\n * Preconfigured HTTP client (e.g. Axios instance with `baseURL` set).\n * Paths in this library are relative to that base (e.g. `/api/v1/...`).\n * Both `get` and `post` are required for auth flows.\n */\n readonly http: HttpClient;\n}\n\nexport interface ApiClient {\n readonly healthCheck: () => ReturnType<typeof fetchHealthCheck>;\n readonly auth: {\n readonly register: (\n body: Parameters<typeof postRegister>[1],\n ) => ReturnType<typeof postRegister>;\n readonly login: (body: Parameters<typeof postLogin>[1]) => ReturnType<typeof postLogin>;\n readonly getGoogleOAuthStart: (redirectUri: string) => ReturnType<typeof getGoogleOAuthStart>;\n readonly postGoogleOAuthCallback: (\n body: Parameters<typeof postGoogleOAuthCallback>[1],\n ) => ReturnType<typeof postGoogleOAuthCallback>;\n readonly refresh: (body: Parameters<typeof postRefresh>[1]) => ReturnType<typeof postRefresh>;\n readonly logout: (body: Parameters<typeof postLogout>[1]) => ReturnType<typeof postLogout>;\n readonly verifyEmail: (\n body: Parameters<typeof patchVerifyEmail>[1],\n ) => ReturnType<typeof patchVerifyEmail>;\n readonly me: (accessToken: string) => ReturnType<typeof getMe>;\n };\n}\n\n/**\n * Creates a typed API client backed by the provided HTTP implementation.\n */\nexport function createApiClient(options: CreateApiClientOptions): ApiClient {\n const { http } = options;\n\n return {\n healthCheck: () => fetchHealthCheck(http),\n auth: {\n register: (body) => postRegister(http, body),\n login: (body) => postLogin(http, body),\n getGoogleOAuthStart: (redirectUri) => getGoogleOAuthStart(http, redirectUri),\n postGoogleOAuthCallback: (body) => postGoogleOAuthCallback(http, body),\n refresh: (body) => postRefresh(http, body),\n logout: (body) => postLogout(http, body),\n verifyEmail: (body) => patchVerifyEmail(http, body),\n me: (accessToken) => getMe(http, accessToken),\n },\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ipetsadmin/api-client",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Client used to interact with Truffa project API",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"author": "",
|
|
39
39
|
"license": "MIT",
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@ipetsadmin/contracts": "
|
|
41
|
+
"@ipetsadmin/contracts": "1.1.7",
|
|
42
42
|
"@eslint/js": "^10.0.1",
|
|
43
43
|
"@types/express": "^5.0.5",
|
|
44
44
|
"@types/node": "^24.10.0",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"typescript-eslint": "^8.58.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
|
-
"@ipetsadmin/contracts": "
|
|
55
|
+
"@ipetsadmin/contracts": ">=1.1.1"
|
|
56
56
|
},
|
|
57
57
|
"publishConfig": {
|
|
58
58
|
"access": "public"
|