@open-kingdom/shared-frontend-data-access-external-api 0.0.2-14 → 0.0.2-15

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.
Files changed (2) hide show
  1. package/README.md +244 -3
  2. package/package.json +2 -1
package/README.md CHANGED
@@ -1,7 +1,248 @@
1
1
  # @open-kingdom/shared-frontend-data-access-external-api
2
2
 
3
- This library was generated with [Nx](https://nx.dev).
3
+ A unified integration layer for connecting any third-party REST API to the application's Redux store via RTK Query. The library provides `createAxiosBaseQuery` an Axios-backed RTK Query base query factory — as the foundation for adding new external API integrations. The Cat Facts API is included as a reference implementation demonstrating the expected pattern; it is not the purpose of the library.
4
4
 
5
- ## Running unit tests
5
+ ---
6
6
 
7
- Run `nx test @open-kingdom/shared-frontend-data-access-external-api` to execute the unit tests via [Vitest](https://vitest.dev/).
7
+ ## Adding a New External API
8
+
9
+ In your application, import `createAxiosBaseQuery` and use it as the `baseQuery` for a new RTK Query `createApi` instance. This lives in your app's own code — not inside this library.
10
+
11
+ ```typescript
12
+ // src/lib/weather-api/weather.api.ts (in your application)
13
+ import { createApi } from '@reduxjs/toolkit/query/react';
14
+ import { createAxiosBaseQuery } from '@open-kingdom/shared-frontend-data-access-external-api';
15
+
16
+ export const weatherApi = createApi({
17
+ reducerPath: 'weatherApi',
18
+ baseQuery: createAxiosBaseQuery({
19
+ baseUrl: 'https://api.openweathermap.org/data/2.5',
20
+ prepareHeaders: (headers) => {
21
+ headers.set('X-Api-Key', process.env.VITE_WEATHER_API_KEY ?? '');
22
+ return headers;
23
+ },
24
+ }),
25
+ endpoints: (builder) => ({
26
+ getCurrentWeather: builder.query<WeatherResponse, string>({
27
+ query: (city) => ({ url: '/weather', params: { q: city } }),
28
+ }),
29
+ }),
30
+ });
31
+
32
+ export const WeatherApiKey = weatherApi.reducerPath;
33
+ export const weatherApiReducer = weatherApi.reducer;
34
+ export const weatherApiMiddleware = weatherApi.middleware;
35
+ export const { useGetCurrentWeatherQuery } = weatherApi;
36
+ ```
37
+
38
+ Register the reducer and middleware in your store:
39
+
40
+ ```typescript
41
+ // src/store.ts (in your application)
42
+ import { configureStore } from '@reduxjs/toolkit';
43
+ import { WeatherApiKey, weatherApiReducer, weatherApiMiddleware } from './lib/weather-api/weather.api';
44
+
45
+ export const store = configureStore({
46
+ reducer: {
47
+ [WeatherApiKey]: weatherApiReducer,
48
+ // ...other reducers
49
+ },
50
+ middleware: (getDefault) => getDefault().concat(weatherApiMiddleware),
51
+ });
52
+ ```
53
+
54
+ Then use the generated hook anywhere in your components:
55
+
56
+ ```tsx
57
+ import { useGetCurrentWeatherQuery } from './lib/weather-api/weather.api';
58
+
59
+ function WeatherWidget({ city }: { city: string }) {
60
+ const { data, isLoading, error } = useGetCurrentWeatherQuery(city);
61
+
62
+ if (isLoading) return <p>Loading...</p>;
63
+ if (error) return <p>Could not load weather</p>;
64
+ return <p>{data?.weather[0].description}</p>;
65
+ }
66
+ ```
67
+
68
+ ---
69
+
70
+ ## Exports
71
+
72
+ ### Base Query Factory
73
+
74
+ | Export | Type | Description |
75
+ | ------------------------------ | ----------------------------------------------- | ----------------------------------------------------- |
76
+ | `createAxiosBaseQuery(config)` | `(config: AxiosBaseQueryConfig) => BaseQueryFn` | Creates an RTK Query `baseQuery` function using Axios |
77
+ | `AxiosBaseQueryConfig` | `interface` | Configuration for the Axios base query |
78
+ | `AxiosBaseQueryArgs` | `interface` | Per-request arguments passed to the query |
79
+ | `AxiosBaseQueryError` | `interface` | Shape of errors returned on Axios failures |
80
+ | `AxiosBaseQueryMeta` | `interface` | Shape of response metadata |
81
+
82
+ ### Cat Facts API (reference implementation)
83
+
84
+ | Export | Type | Description |
85
+ | ----------------------- | ----------------------------------------------------------------- | ---------------------------------------------------------------------------------------- |
86
+ | `catFactsApi` | `Api<...>` | RTK Query `createApi` instance for `https://catfact.ninja`, `reducerPath: 'catFactsApi'` |
87
+ | `CatFactsApiKey` | `'catFactsApi'` | The reducer path string constant |
88
+ | `catFactsApiReducer` | `Reducer` | `catFactsApi.reducer` |
89
+ | `catFactsApiMiddleware` | `Middleware` | `catFactsApi.middleware` |
90
+ | `useGetFactQuery` | `QueryHook<CatFact, void>` | RTK Query hook for `GET /fact` |
91
+ | `useGetFactsQuery` | `QueryHook<PaginatedResponse<CatFact>, PaginationParams \| void>` | RTK Query hook for `GET /facts` |
92
+ | `useGetBreedsQuery` | `QueryHook<PaginatedResponse<Breed>, PaginationParams \| void>` | RTK Query hook for `GET /breeds` |
93
+
94
+ ---
95
+
96
+ ## Type Definitions
97
+
98
+ ### `AxiosBaseQueryConfig`
99
+
100
+ | Property | Type | Required | Default | Description |
101
+ | ---------------- | ------------------------------------------------------------ | -------- | ------- | ---------------------------------------------------------------------- |
102
+ | `baseUrl` | `string` | Yes | — | The base URL for all requests made by this query function |
103
+ | `prepareHeaders` | `(headers: AxiosHeaders, api: BaseQueryApi) => AxiosHeaders` | No | — | Optional hook to inject headers (e.g. auth tokens) before each request |
104
+
105
+ ### `AxiosBaseQueryArgs`
106
+
107
+ | Property | Type | Required | Default | Description |
108
+ | --------- | ------------------------------ | -------- | ------- | ---------------------------- |
109
+ | `url` | `string` | Yes | — | Path appended to `baseUrl` |
110
+ | `method` | `AxiosRequestConfig['method']` | No | `'GET'` | HTTP method |
111
+ | `params` | `Record<string, unknown>` | No | — | URL query parameters |
112
+ | `body` | `unknown` | No | — | Request body |
113
+ | `headers` | `Record<string, string>` | No | — | Per-request header overrides |
114
+
115
+ Additional properties are passed through to the Axios config object.
116
+
117
+ ### `AxiosBaseQueryError`
118
+
119
+ | Property | Type | Required | Description |
120
+ | --------- | --------- | -------- | ------------------------------------- |
121
+ | `status` | `number` | No | HTTP status code |
122
+ | `data` | `unknown` | No | Response body from the failed request |
123
+ | `headers` | `unknown` | No | Response headers |
124
+
125
+ ### `AxiosBaseQueryMeta`
126
+
127
+ | Property | Type | Required | Description |
128
+ | --------- | -------------------- | -------- | ------------------------------------- |
129
+ | `headers` | `unknown` | No | Response headers |
130
+ | `status` | `number` | No | HTTP status code |
131
+ | `config` | `AxiosRequestConfig` | No | The Axios config used for the request |
132
+
133
+ ### `CatFact`
134
+
135
+ | Property | Type | Description |
136
+ | -------- | -------- | ---------------------------- |
137
+ | `fact` | `string` | The fact text |
138
+ | `length` | `number` | Character length of the fact |
139
+
140
+ ### `Breed`
141
+
142
+ | Property | Type | Description |
143
+ | --------- | -------- | ------------------ |
144
+ | `breed` | `string` | Breed name |
145
+ | `country` | `string` | Country of origin |
146
+ | `origin` | `string` | Origin description |
147
+ | `coat` | `string` | Coat type |
148
+ | `pattern` | `string` | Coat pattern |
149
+
150
+ ### `PaginatedResponse<T>`
151
+
152
+ | Property | Type | Description |
153
+ | -------------- | -------- | -------------------------------------- |
154
+ | `current_page` | `number` | Current page number |
155
+ | `data` | `T[]` | Array of items for the current page |
156
+ | `last_page` | `number` | Total number of pages |
157
+ | `total` | `number` | Total number of items across all pages |
158
+
159
+ ### `PaginationParams`
160
+
161
+ | Property | Type | Required | Description |
162
+ | -------- | -------- | -------- | ------------------------ |
163
+ | `page` | `number` | No | Page number to fetch |
164
+ | `limit` | `number` | No | Number of items per page |
165
+
166
+ Additional properties are forwarded to the query string.
167
+
168
+ ---
169
+
170
+ ## Setup
171
+
172
+ ### Adding the Cat Facts reference API to the store
173
+
174
+ ```typescript
175
+ import { configureStore } from '@reduxjs/toolkit';
176
+ import { CatFactsApiKey, catFactsApiReducer, catFactsApiMiddleware } from '@open-kingdom/shared-frontend-data-access-external-api';
177
+
178
+ export const store = configureStore({
179
+ reducer: {
180
+ [CatFactsApiKey]: catFactsApiReducer, // 'catFactsApi'
181
+ },
182
+ middleware: (getDefault) => getDefault().concat(catFactsApiMiddleware),
183
+ });
184
+ ```
185
+
186
+ ---
187
+
188
+ ## Usage Examples
189
+
190
+ ### Fetch a random cat fact
191
+
192
+ ```tsx
193
+ import { useGetFactQuery } from '@open-kingdom/shared-frontend-data-access-external-api';
194
+
195
+ function CatFactWidget() {
196
+ const { data, isLoading, error } = useGetFactQuery();
197
+
198
+ if (isLoading) return <p>Loading...</p>;
199
+ if (error) return <p>Error loading fact</p>;
200
+ return <p>{data?.fact}</p>;
201
+ }
202
+ ```
203
+
204
+ ### Fetch paginated facts
205
+
206
+ ```tsx
207
+ import { useGetFactsQuery } from '@open-kingdom/shared-frontend-data-access-external-api';
208
+
209
+ function CatFactsList() {
210
+ const { data } = useGetFactsQuery({ page: 1, limit: 10 });
211
+
212
+ return (
213
+ <ul>
214
+ {data?.data.map((item, i) => (
215
+ <li key={i}>{item.fact}</li>
216
+ ))}
217
+ </ul>
218
+ );
219
+ }
220
+ ```
221
+
222
+ ### Fetch cat breeds
223
+
224
+ ```tsx
225
+ import { useGetBreedsQuery } from '@open-kingdom/shared-frontend-data-access-external-api';
226
+
227
+ function BreedList() {
228
+ const { data } = useGetBreedsQuery({ page: 1, limit: 25 });
229
+
230
+ return (
231
+ <ul>
232
+ {data?.data.map((breed) => (
233
+ <li key={breed.breed}>
234
+ {breed.breed} — {breed.country}
235
+ </li>
236
+ ))}
237
+ </ul>
238
+ );
239
+ }
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Testing
245
+
246
+ ```bash
247
+ nx test shared-frontend-data-access-external-api
248
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-kingdom/shared-frontend-data-access-external-api",
3
- "version": "0.0.2-14",
3
+ "version": "0.0.2-15",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -18,6 +18,7 @@
18
18
  }
19
19
  },
20
20
  "files": [
21
+ "README.md",
21
22
  "dist",
22
23
  "!**/*.tsbuildinfo"
23
24
  ],