@fjell/client-api 4.4.9 → 4.4.10

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.
@@ -0,0 +1,18 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+
4
+ <head>
5
+ <meta charset="UTF-8" />
6
+ <link rel="icon" type="image/svg+xml" href="/fjell-icon.svg" />
7
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
8
+ <title>Fjell Client API - TypeScript Client Library</title>
9
+ <meta name="description"
10
+ content="Client API for Fjell - A powerful TypeScript client library for service consumption">
11
+ </head>
12
+
13
+ <body>
14
+ <div id="root"></div>
15
+ <script type="module" src="/src/main.tsx"></script>
16
+ </body>
17
+
18
+ </html>
@@ -0,0 +1,35 @@
1
+ {
2
+ "name": "fjell-client-api-docs",
3
+ "private": true,
4
+ "version": "0.0.0",
5
+ "type": "module",
6
+ "scripts": {
7
+ "dev": "vite",
8
+ "build": "tsc && vite build",
9
+ "preview": "vite preview",
10
+ "test": "vitest run --coverage",
11
+ "test:watch": "vitest --watch"
12
+ },
13
+ "dependencies": {
14
+ "react": "^19.1.0",
15
+ "react-dom": "^19.1.0",
16
+ "react-markdown": "^10.1.0",
17
+ "react-syntax-highlighter": "^15.6.1",
18
+ "remark-gfm": "^4.0.1"
19
+ },
20
+ "devDependencies": {
21
+ "@testing-library/jest-dom": "^6.6.3",
22
+ "@testing-library/react": "^16.3.0",
23
+ "@testing-library/user-event": "^14.6.1",
24
+ "@types/react": "^19.1.8",
25
+ "@types/react-dom": "^19.1.6",
26
+ "@types/react-syntax-highlighter": "^15.5.13",
27
+ "@vitejs/plugin-react": "^4.6.0",
28
+ "@vitest/coverage-v8": "^3.2.4",
29
+ "@vitest/ui": "^3.2.4",
30
+ "jsdom": "^26.1.0",
31
+ "typescript": "^5.8.3",
32
+ "vite": "^7.0.0",
33
+ "vitest": "^3.2.4"
34
+ }
35
+ }
@@ -0,0 +1,165 @@
1
+ # Fjell Client API
2
+
3
+ A comprehensive HTTP client library for the Fjell ecosystem. The Client API provides powerful abstractions for HTTP-based data operations, making it easy to build robust client applications that consume REST APIs.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @fjell/client-api
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { createPItemApi, createCItemApi } from '@fjell/client-api'
15
+
16
+ // Configure API endpoints
17
+ const apiConfig = {
18
+ baseUrl: 'https://api.example.com',
19
+ headers: { 'Authorization': 'Bearer token' }
20
+ }
21
+
22
+ // Create Primary Item API (independent entities)
23
+ const userApi = createPItemApi<User, 'user'>('user', ['users'], apiConfig)
24
+
25
+ // Create Contained Item API (hierarchical entities)
26
+ const taskApi = createCItemApi<Task, 'task', 'user'>('task', ['users', 'tasks'], apiConfig)
27
+
28
+ // Basic operations
29
+ const users = await userApi.all(query)
30
+ const user = await userApi.create(userData)
31
+ const tasks = await taskApi.all(query, [userId]) // Location-based query
32
+ ```
33
+
34
+ ## Key Features
35
+
36
+ - **HTTP-based Operations**: Complete CRUD operations over HTTP
37
+ - **Type-safe APIs**: Full TypeScript support with generic type parameters
38
+ - **Hierarchical Data**: Support for nested resource relationships
39
+ - **Business Logic**: Actions and facets for complex operations
40
+ - **Authentication**: Built-in support for various auth patterns
41
+ - **Error Handling**: Comprehensive error handling and retry logic
42
+
43
+ ## Architecture
44
+
45
+ The Client API is built around two main concepts:
46
+
47
+ ### Primary Items (PItemApi)
48
+ Independent entities that exist at the top level of your API hierarchy. These represent resources that don't require parent context, such as Users, Products, or Organizations.
49
+
50
+ ### Contained Items (CItemApi)
51
+ Entities that belong to parent resources and require location context. These represent hierarchical data like Tasks within Projects, OrderItems within Orders, or Comments within Posts.
52
+
53
+ This design mirrors RESTful API patterns while providing powerful abstractions for complex business operations.
54
+
55
+ ## Core Concepts
56
+
57
+ ### API Configuration
58
+ Configure your client with base URLs, authentication headers, and other options:
59
+
60
+ ```typescript
61
+ const config = {
62
+ baseUrl: 'https://api.example.com',
63
+ headers: {
64
+ 'Content-Type': 'application/json',
65
+ 'Authorization': 'Bearer your-token'
66
+ },
67
+ timeout: 5000
68
+ }
69
+ ```
70
+
71
+ ### Primary Item API
72
+ For independent resources:
73
+
74
+ ```typescript
75
+ const userApi = createPItemApi<User, 'user'>('user', ['users'], config)
76
+
77
+ // CRUD operations
78
+ const users = await userApi.all()
79
+ const user = await userApi.get(userKey)
80
+ const newUser = await userApi.create({ name: 'John', email: 'john@example.com' })
81
+ const updatedUser = await userApi.update(userKey, { name: 'John Smith' })
82
+ await userApi.remove(userKey)
83
+ ```
84
+
85
+ ### Contained Item API
86
+ For hierarchical resources:
87
+
88
+ ```typescript
89
+ const taskApi = createCItemApi<Task, 'task', 'user'>('task', ['users', 'tasks'], config)
90
+
91
+ // Operations with location context
92
+ const userTasks = await taskApi.all({}, [userId])
93
+ const task = await taskApi.get(taskKey)
94
+ const newTask = await taskApi.create({ title: 'Complete project' }, [userId])
95
+ ```
96
+
97
+ ### Actions and Facets
98
+ Execute business logic and retrieve analytics:
99
+
100
+ ```typescript
101
+ // Actions - execute business operations
102
+ await userApi.action(userKey, 'activate', { reason: 'manual activation' })
103
+ await taskApi.action(taskKey, 'complete', { completedAt: new Date() })
104
+
105
+ // Facets - retrieve computed data and analytics
106
+ const userStats = await userApi.facet(userKey, 'activity-stats')
107
+ const taskMetrics = await taskApi.allFacet('completion-metrics', { period: 'monthly' })
108
+ ```
109
+
110
+ ## Examples
111
+
112
+ See the `/examples` directory for comprehensive usage patterns:
113
+
114
+ - **Simple Example**: Basic CRUD operations and client setup
115
+ - **Multi-Level Keys**: Complex hierarchical data with nested relationships
116
+ - **Enterprise Example**: Complete business application with e-commerce workflows
117
+
118
+ ## TypeScript Support
119
+
120
+ The Client API is built with TypeScript-first design, providing:
121
+
122
+ - Full type safety for API operations
123
+ - Generic type parameters for custom data models
124
+ - Compile-time validation of API method signatures
125
+ - IntelliSense support for better developer experience
126
+
127
+ ## Error Handling
128
+
129
+ Built-in error handling with detailed error information:
130
+
131
+ ```typescript
132
+ try {
133
+ const user = await userApi.get(userKey)
134
+ } catch (error) {
135
+ console.error('API error:', error.message)
136
+ // Handle specific error types
137
+ if (error.status === 404) {
138
+ // Handle not found
139
+ } else if (error.status === 401) {
140
+ // Handle authentication error
141
+ }
142
+ }
143
+ ```
144
+
145
+ ## Advanced Features
146
+
147
+ ### Authentication
148
+ Support for various authentication patterns including Bearer tokens, API keys, and custom headers.
149
+
150
+ ### Request Configuration
151
+ Fine-tune requests with timeout settings, retry logic, and custom middleware.
152
+
153
+ ### Response Processing
154
+ Automatic response parsing and error handling for consistent API interactions.
155
+
156
+ ### Location-based Operations
157
+ Powerful location context system for hierarchical data operations.
158
+
159
+ ## Contributing
160
+
161
+ This library is part of the Fjell ecosystem. For contributing guidelines and development setup, please refer to the main Fjell documentation.
162
+
163
+ ## License
164
+
165
+ Licensed under Apache-2.0. See LICENSE file for details.
@@ -0,0 +1,408 @@
1
+ # API Reference
2
+
3
+ Complete reference for all Client API interfaces and methods.
4
+
5
+ ## Core Interfaces
6
+
7
+ ### PItemApi<V, S>
8
+
9
+ Primary Item API for independent entities that exist at the top level of your API hierarchy.
10
+
11
+ **Type Parameters:**
12
+ - `V` - The value type returned from API operations
13
+ - `S` - The string literal type representing the item type
14
+
15
+ #### Methods
16
+
17
+ ##### `all(query?: ItemQuery): Promise<V[]>`
18
+ Retrieve all items matching the query criteria.
19
+
20
+ **Parameters:**
21
+ - `query` (optional) - Query parameters for filtering and pagination
22
+
23
+ **Returns:** Promise resolving to an array of items
24
+
25
+ **Example:**
26
+ ```typescript
27
+ const users = await userApi.all({ limit: 10, offset: 0 })
28
+ ```
29
+
30
+ ##### `create(item: Partial<Item<S>>): Promise<V>`
31
+ Create a new item.
32
+
33
+ **Parameters:**
34
+ - `item` - Partial item data for creation
35
+
36
+ **Returns:** Promise resolving to the created item
37
+
38
+ **Example:**
39
+ ```typescript
40
+ const user = await userApi.create({
41
+ name: 'John Doe',
42
+ email: 'john@example.com'
43
+ })
44
+ ```
45
+
46
+ ##### `get(key: PriKey<S>): Promise<V>`
47
+ Retrieve a specific item by its key.
48
+
49
+ **Parameters:**
50
+ - `key` - Primary key identifying the item
51
+
52
+ **Returns:** Promise resolving to the item
53
+
54
+ **Example:**
55
+ ```typescript
56
+ const user = await userApi.get(userKey)
57
+ ```
58
+
59
+ ##### `update(key: PriKey<S>, updates: Partial<Item<S>>): Promise<V>`
60
+ Update an existing item.
61
+
62
+ **Parameters:**
63
+ - `key` - Primary key identifying the item
64
+ - `updates` - Partial updates to apply
65
+
66
+ **Returns:** Promise resolving to the updated item
67
+
68
+ **Example:**
69
+ ```typescript
70
+ const updatedUser = await userApi.update(userKey, {
71
+ name: 'John Smith'
72
+ })
73
+ ```
74
+
75
+ ##### `remove(key: PriKey<S>): Promise<boolean>`
76
+ Delete an item.
77
+
78
+ **Parameters:**
79
+ - `key` - Primary key identifying the item
80
+
81
+ **Returns:** Promise resolving to true if deletion was successful
82
+
83
+ **Example:**
84
+ ```typescript
85
+ const deleted = await userApi.remove(userKey)
86
+ ```
87
+
88
+ ##### `action(key: PriKey<S>, action: string, body?: any): Promise<any>`
89
+ Execute a business action on a specific item.
90
+
91
+ **Parameters:**
92
+ - `key` - Primary key identifying the item
93
+ - `action` - Name of the action to execute
94
+ - `body` (optional) - Action parameters
95
+
96
+ **Returns:** Promise resolving to action result
97
+
98
+ **Example:**
99
+ ```typescript
100
+ await userApi.action(userKey, 'activate', { reason: 'manual activation' })
101
+ ```
102
+
103
+ ##### `find(finder: string, params?: any): Promise<V[]>`
104
+ Execute a custom finder operation.
105
+
106
+ **Parameters:**
107
+ - `finder` - Name of the finder
108
+ - `params` (optional) - Finder parameters
109
+
110
+ **Returns:** Promise resolving to an array of found items
111
+
112
+ **Example:**
113
+ ```typescript
114
+ const activeUsers = await userApi.find('active-users', { since: '2024-01-01' })
115
+ ```
116
+
117
+ ##### `facet(key: PriKey<S>, facet: string, params?: any): Promise<any>`
118
+ Retrieve computed data or analytics for a specific item.
119
+
120
+ **Parameters:**
121
+ - `key` - Primary key identifying the item
122
+ - `facet` - Name of the facet
123
+ - `params` (optional) - Facet parameters
124
+
125
+ **Returns:** Promise resolving to facet data
126
+
127
+ **Example:**
128
+ ```typescript
129
+ const userStats = await userApi.facet(userKey, 'activity-stats')
130
+ ```
131
+
132
+ ##### `allAction(action: string, body?: any): Promise<V[]>`
133
+ Execute a business action on all items or collections.
134
+
135
+ **Parameters:**
136
+ - `action` - Name of the action to execute
137
+ - `body` (optional) - Action parameters
138
+
139
+ **Returns:** Promise resolving to action results
140
+
141
+ **Example:**
142
+ ```typescript
143
+ const results = await userApi.allAction('bulk-update', { status: 'active' })
144
+ ```
145
+
146
+ ##### `allFacet(facet: string, params?: any): Promise<any>`
147
+ Retrieve computed data or analytics for collections.
148
+
149
+ **Parameters:**
150
+ - `facet` - Name of the facet
151
+ - `params` (optional) - Facet parameters
152
+
153
+ **Returns:** Promise resolving to facet data
154
+
155
+ **Example:**
156
+ ```typescript
157
+ const userAnalytics = await userApi.allFacet('engagement-metrics', { period: 'monthly' })
158
+ ```
159
+
160
+ ### CItemApi<V, S, L1, L2, L3, L4, L5>
161
+
162
+ Contained Item API for hierarchical entities that belong to parent resources and require location context.
163
+
164
+ **Type Parameters:**
165
+ - `V` - The value type returned from API operations
166
+ - `S` - The string literal type representing the item type
167
+ - `L1, L2, L3, L4, L5` - Location hierarchy types (up to 5 levels)
168
+
169
+ **Extends:** All PItemApi methods plus location-aware variants
170
+
171
+ #### Location-Aware Methods
172
+
173
+ ##### `all(query: ItemQuery, locations?: LocKeyArray<L1, L2, L3, L4, L5>): Promise<V[]>`
174
+ Retrieve all items within a specific location context.
175
+
176
+ **Parameters:**
177
+ - `query` - Query parameters
178
+ - `locations` (optional) - Array of location keys defining the context
179
+
180
+ **Returns:** Promise resolving to an array of items
181
+
182
+ **Example:**
183
+ ```typescript
184
+ // Get all tasks for a specific user
185
+ const tasks = await taskApi.all({}, [userId])
186
+
187
+ // Get all employees in a specific department
188
+ const employees = await employeeApi.all({}, [orgId, deptId])
189
+ ```
190
+
191
+ ##### `create(item: Partial<Item<S>>, locations?: LocKeyArray<L1, L2, L3, L4, L5>): Promise<V>`
192
+ Create a new item within a specific location context.
193
+
194
+ **Parameters:**
195
+ - `item` - Partial item data for creation
196
+ - `locations` (optional) - Array of location keys defining the context
197
+
198
+ **Returns:** Promise resolving to the created item
199
+
200
+ **Example:**
201
+ ```typescript
202
+ const task = await taskApi.create({
203
+ title: 'Complete project'
204
+ }, [userId])
205
+ ```
206
+
207
+ ##### `find(finder: string, params?: any, locations?: LocKeyArray<L1, L2, L3, L4, L5>): Promise<V[]>`
208
+ Execute a custom finder within a location context.
209
+
210
+ ##### `allAction(action: string, body?: any, locations?: LocKeyArray<L1, L2, L3, L4, L5>): Promise<V[]>`
211
+ Execute actions on collections within a location context.
212
+
213
+ ##### `allFacet(facet: string, params?: any, locations?: LocKeyArray<L1, L2, L3, L4, L5>): Promise<any>`
214
+ Retrieve analytics for collections within a location context.
215
+
216
+ ## Configuration
217
+
218
+ ### ApiConfig
219
+
220
+ Configuration object for API instances.
221
+
222
+ ```typescript
223
+ interface ApiConfig {
224
+ baseUrl: string;
225
+ headers?: { [key: string]: string };
226
+ timeout?: number;
227
+ retries?: number;
228
+ readAuthenticated?: boolean;
229
+ writeAuthenticated?: boolean;
230
+ }
231
+ ```
232
+
233
+ **Properties:**
234
+ - `baseUrl` - Base URL for API endpoints
235
+ - `headers` (optional) - Default headers to include with requests
236
+ - `timeout` (optional) - Request timeout in milliseconds
237
+ - `retries` (optional) - Number of retry attempts for failed requests
238
+ - `readAuthenticated` (optional) - Whether read operations require authentication
239
+ - `writeAuthenticated` (optional) - Whether write operations require authentication
240
+
241
+ **Example:**
242
+ ```typescript
243
+ const config: ApiConfig = {
244
+ baseUrl: 'https://api.example.com',
245
+ headers: {
246
+ 'Content-Type': 'application/json',
247
+ 'Authorization': 'Bearer token'
248
+ },
249
+ timeout: 5000,
250
+ retries: 3,
251
+ readAuthenticated: true,
252
+ writeAuthenticated: true
253
+ }
254
+ ```
255
+
256
+ ## Factory Functions
257
+
258
+ ### createPItemApi
259
+
260
+ Creates a Primary Item API instance.
261
+
262
+ ```typescript
263
+ function createPItemApi<V, S extends string>(
264
+ itemType: S,
265
+ pathSegments: string[],
266
+ config: ApiConfig
267
+ ): PItemApi<V, S>
268
+ ```
269
+
270
+ **Parameters:**
271
+ - `itemType` - String literal identifying the item type
272
+ - `pathSegments` - Array of path segments for API endpoints
273
+ - `config` - API configuration
274
+
275
+ **Example:**
276
+ ```typescript
277
+ const userApi = createPItemApi<User, 'user'>('user', ['users'], config)
278
+ ```
279
+
280
+ ### createCItemApi
281
+
282
+ Creates a Contained Item API instance.
283
+
284
+ ```typescript
285
+ function createCItemApi<V, S extends string, L1 extends string, L2 extends string = never, L3 extends string = never, L4 extends string = never, L5 extends string = never>(
286
+ itemType: S,
287
+ pathSegments: string[],
288
+ config: ApiConfig
289
+ ): CItemApi<V, S, L1, L2, L3, L4, L5>
290
+ ```
291
+
292
+ **Parameters:**
293
+ - `itemType` - String literal identifying the item type
294
+ - `pathSegments` - Array of path segments for API endpoints (including parent segments)
295
+ - `config` - API configuration
296
+
297
+ **Example:**
298
+ ```typescript
299
+ // Single-level containment
300
+ const taskApi = createCItemApi<Task, 'task', 'user'>('task', ['users', 'tasks'], config)
301
+
302
+ // Multi-level containment
303
+ const employeeApi = createCItemApi<Employee, 'employee', 'organization', 'department'>(
304
+ 'employee',
305
+ ['organizations', 'departments', 'employees'],
306
+ config
307
+ )
308
+ ```
309
+
310
+ ## Error Handling
311
+
312
+ The Client API provides comprehensive error handling with detailed error information.
313
+
314
+ ### Error Types
315
+
316
+ - **NetworkError** - Network connectivity issues
317
+ - **AuthenticationError** - Authentication failures
318
+ - **AuthorizationError** - Authorization/permission issues
319
+ - **ValidationError** - Request validation failures
320
+ - **NotFoundError** - Resource not found
321
+ - **ServerError** - Server-side errors
322
+
323
+ ### Error Handling Patterns
324
+
325
+ ```typescript
326
+ try {
327
+ const user = await userApi.get(userKey)
328
+ } catch (error) {
329
+ if (error instanceof NotFoundError) {
330
+ console.log('User not found')
331
+ } else if (error instanceof AuthenticationError) {
332
+ // Redirect to login
333
+ } else if (error instanceof ValidationError) {
334
+ // Handle validation errors
335
+ console.error('Validation errors:', error.details)
336
+ } else {
337
+ // Handle other errors
338
+ console.error('API error:', error.message)
339
+ }
340
+ }
341
+ ```
342
+
343
+ ## Best Practices
344
+
345
+ ### 1. Type Safety
346
+ Always provide proper TypeScript types for your data models:
347
+
348
+ ```typescript
349
+ interface User {
350
+ id: string;
351
+ name: string;
352
+ email: string;
353
+ createdAt: Date;
354
+ updatedAt: Date;
355
+ }
356
+
357
+ const userApi = createPItemApi<User, 'user'>('user', ['users'], config)
358
+ ```
359
+
360
+ ### 2. Error Handling
361
+ Implement comprehensive error handling:
362
+
363
+ ```typescript
364
+ const createUser = async (userData: Partial<User>) => {
365
+ try {
366
+ return await userApi.create(userData)
367
+ } catch (error) {
368
+ // Log error and handle appropriately
369
+ console.error('Failed to create user:', error)
370
+ throw error
371
+ }
372
+ }
373
+ ```
374
+
375
+ ### 3. Configuration Management
376
+ Use environment-specific configuration:
377
+
378
+ ```typescript
379
+ const config = {
380
+ baseUrl: process.env.API_BASE_URL || 'http://localhost:3000',
381
+ headers: {
382
+ 'Authorization': `Bearer ${process.env.API_TOKEN}`
383
+ }
384
+ }
385
+ ```
386
+
387
+ ### 4. Location Context
388
+ Always provide proper location context for contained items:
389
+
390
+ ```typescript
391
+ // Good - specific location context
392
+ const userTasks = await taskApi.all({}, [userId])
393
+
394
+ // Avoid - missing location context may return unexpected results
395
+ const allTasks = await taskApi.all({})
396
+ ```
397
+
398
+ ### 5. Query Optimization
399
+ Use appropriate queries and pagination:
400
+
401
+ ```typescript
402
+ const users = await userApi.all({
403
+ limit: 50,
404
+ offset: 0,
405
+ sort: 'createdAt:desc',
406
+ filter: 'status:active'
407
+ })
408
+ ```