@fjell/client-api 4.4.46 → 4.4.48

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@fjell/client-api",
3
3
  "description": "Client API for Fjell",
4
- "version": "4.4.46",
4
+ "version": "4.4.48",
5
5
  "keywords": [
6
6
  "client",
7
7
  "api",
@@ -38,30 +38,31 @@
38
38
  "docs:test": "cd docs && npm run test"
39
39
  },
40
40
  "dependencies": {
41
- "@fjell/core": "^4.4.50",
42
- "@fjell/http-api": "^4.4.42",
43
- "@fjell/logging": "^4.4.49",
44
- "@fjell/registry": "^4.4.52",
41
+ "@fjell/core": "^4.4.53",
42
+ "@fjell/http-api": "^4.4.45",
43
+ "@fjell/logging": "^4.4.52",
44
+ "@fjell/registry": "^4.4.55",
45
45
  "deepmerge": "^4.3.1"
46
46
  },
47
47
  "devDependencies": {
48
48
  "@eslint/eslintrc": "^3.3.1",
49
- "@eslint/js": "^9.33.0",
50
- "@fjell/eslint-config": "^1.1.25",
49
+ "@eslint/js": "^9.38.0",
50
+ "@fjell/common-config": "^1.1.29",
51
51
  "@tsconfig/recommended": "^1.0.10",
52
- "@types/node": "^24.2.1",
53
- "@typescript-eslint/eslint-plugin": "^8.39.0",
54
- "@typescript-eslint/parser": "^8.39.0",
55
- "@vitest/coverage-istanbul": "^3.2.4",
56
- "@vitest/coverage-v8": "^3.2.4",
57
- "@vitest/ui": "^3.2.4",
58
- "concurrently": "^9.2.0",
59
- "esbuild": "0.25.9",
60
- "eslint": "^9.33.0",
61
- "jsdom": "^26.1.0",
62
- "typescript": "^5.9.2",
63
- "undici": "^7.13.0",
64
- "vitest": "^3.2.4",
52
+ "@types/node": "^24.9.1",
53
+ "@typescript-eslint/eslint-plugin": "^8.46.2",
54
+ "@typescript-eslint/parser": "^8.46.2",
55
+ "@vitest/coverage-istanbul": "^4.0.1",
56
+ "@vitest/coverage-v8": "^4.0.1",
57
+ "@vitest/ui": "^4.0.1",
58
+ "concurrently": "^9.2.1",
59
+ "esbuild": "0.25.11",
60
+ "eslint": "^9.38.0",
61
+ "jsdom": "^27.0.1",
62
+ "prismjs": ">=1.30.0",
63
+ "typescript": "^5.9.3",
64
+ "undici": "^7.16.0",
65
+ "vitest": "^4.0.1",
65
66
  "vitest-fetch-mock": "^0.4.5"
66
67
  },
67
68
  "repository": {
@@ -69,6 +70,6 @@
69
70
  "url": "git+https://github.com/getfjell/client-api.git"
70
71
  },
71
72
  "overrides": {
72
- "esbuild": "0.25.9"
73
+ "esbuild": "0.25.11"
73
74
  }
74
75
  }
@@ -1,153 +0,0 @@
1
- # Location Key Ordering in Client API
2
-
3
- ## Overview
4
-
5
- When accessing nested/contained entities in Fjell, the **order of location keys matters**. The client API now includes **automatic validation** that will throw an error if location keys are passed in the wrong order, preventing malformed URL paths from being generated.
6
-
7
- ## Automatic Validation (New Feature)
8
-
9
- As of this update, the client API automatically validates location key ordering and will throw a descriptive error if keys are out of order. This prevents silent failures where malformed paths would result in 404 errors.
10
-
11
- ### What Gets Validated
12
-
13
- - Location keys must appear in ascending order according to the `pathNames` hierarchy
14
- - The validation compares each key's type (`kt`) against the `pathNames` array
15
- - If a key appears "earlier" in the hierarchy than the previous key, an error is thrown
16
-
17
- ### Example Validation Error
18
-
19
- ```typescript
20
- Error: Location keys must be ordered from parent to child according to the entity hierarchy.
21
- Expected order based on pathNames: [fjell/order, orderForm, orderNoseShape].
22
- Received key types in order: [orderForm, order].
23
- Key "order" is out of order - it should appear earlier in the hierarchy.
24
- ```
25
-
26
- ## How It Works
27
-
28
- The `getPath()` function in `Utilities.ts` processes keys in the order they are provided. The new `validateLocationKeyOrder()` function checks that location keys match the expected hierarchy before building the path.
29
-
30
- ### Example: Three-Level Hierarchy
31
-
32
- Given this entity hierarchy:
33
- ```
34
- order (primary)
35
- └─ orderForm (contained in order)
36
- └─ orderNoseShape (contained in orderForm)
37
- ```
38
-
39
- With `pathNames: ["fjell/order", "orderForm", "orderNoseShape"]`
40
-
41
- ### ✅ Correct Usage
42
-
43
- ```typescript
44
- const orderKey: LocKey<"order"> = { kt: "order", lk: "26669" };
45
- const orderFormKey: LocKey<"orderForm"> = { kt: "orderForm", lk: "26693" };
46
-
47
- // Keys must be ordered from PARENT to CHILD
48
- const locations = [orderKey, orderFormKey];
49
-
50
- api.one({}, locations);
51
- // Result: /fjell/order/26669/orderForm/26693/orderNoseShape ✅
52
- ```
53
-
54
- ### ❌ Wrong Usage (Now Throws Error)
55
-
56
- ```typescript
57
- // WRONG: orderForm before order
58
- const locations = [orderFormKey, orderKey];
59
-
60
- api.one({}, locations);
61
- // Throws Error: Location keys must be ordered from parent to child according to the entity hierarchy.
62
- // Expected order based on pathNames: [fjell/order, orderForm, orderNoseShape].
63
- // Received key types in order: [orderForm, order].
64
- // Key "order" is out of order - it should appear earlier in the hierarchy.
65
- ```
66
-
67
- **Before this update:** This would have silently created a malformed path: `/orderForm/26693/fjell/order/26669/orderNoseShape`
68
-
69
- **Now:** An error is thrown immediately, making the issue obvious and preventing network requests with bad paths.
70
-
71
- ## Rules for Location Key Ordering
72
-
73
- 1. **Always order from outermost to innermost**: `[grandparent, parent, child]`
74
- 2. **Match the hierarchy defined by your data model**: The order should reflect how entities are nested
75
- 3. **For ComKeys**: The `loc` array should also follow this ordering
76
-
77
- ### ComKey Example
78
-
79
- ```typescript
80
- // For accessing a specific orderNoseShape item
81
- const comKey = {
82
- kt: "orderNoseShape",
83
- pk: "nose-123",
84
- loc: [
85
- { kt: "order", lk: "26669" }, // Parent first
86
- { kt: "orderForm", lk: "26693" } // Child second
87
- ]
88
- };
89
-
90
- api.get(comKey);
91
- // Result: /fjell/order/26669/orderForm/26693/orderNoseShape/nose-123 ✅
92
- ```
93
-
94
- ## Debugging Tips
95
-
96
- 1. **Enable logging**: The `Utilities.ts` logger logs the keys and pathNames being processed
97
- 2. **Check the generated path**: Use browser DevTools Network tab to see the actual HTTP request
98
- 3. **Verify key order**: Print/log your `locations` array before passing it to API methods
99
- 4. **Use the type system**: TypeScript generics enforce the location types but not their order
100
-
101
- ## Common Mistakes
102
-
103
- ### Mistake 1: Building keys in reverse
104
- ```typescript
105
- // Building keys as you traverse from child to parent
106
- const keys = [];
107
- keys.push(orderFormKey); // ❌ Adding child first
108
- keys.push(orderKey); // ❌ Adding parent second
109
- ```
110
-
111
- **Fix**: Build keys from parent to child
112
- ```typescript
113
- const keys = [];
114
- keys.push(orderKey); // ✅ Parent first
115
- keys.push(orderFormKey); // ✅ Child second
116
- ```
117
-
118
- ### Mistake 2: Not considering the full hierarchy
119
- ```typescript
120
- // Only providing the immediate parent
121
- const locations = [orderFormKey]; // ❌ Missing orderKey
122
- ```
123
-
124
- **Fix**: Include all ancestors
125
- ```typescript
126
- const locations = [orderKey, orderFormKey]; // ✅ Complete hierarchy
127
- ```
128
-
129
- ## Test Coverage
130
-
131
- See `tests/Utilities.test.ts` for comprehensive examples:
132
- - ✅ Correct ordering: "should generate path for collection access with location keys only"
133
- - ✅ Error on wrong ordering: "should throw error when location keys are in wrong order"
134
- - ✅ ComKey usage: "should generate path for nested entities with correct order"
135
- - ✅ Error message validation: "should throw error with helpful message explaining the issue"
136
-
137
- ## Benefits of Validation
138
-
139
- 1. **Fail fast**: Errors are caught immediately at the API call site, not after a failed HTTP request
140
- 2. **Clear error messages**: The error tells you exactly what went wrong and what the correct order should be
141
- 3. **Prevents debugging confusion**: No more hunting through logs to figure out why you're getting 404 errors
142
- 4. **Type-safe**: Works seamlessly with TypeScript's type system
143
- 5. **Zero runtime cost for correct code**: Validation only runs when keys are actually used
144
-
145
- ## Implementation Details
146
-
147
- The validation function (`validateLocationKeyOrder` in `Utilities.ts`):
148
- - Extracts location keys from the provided keys array
149
- - Builds a map of key types to their expected position in the hierarchy
150
- - Validates that location keys appear in strictly ascending order
151
- - Throws a detailed error if validation fails
152
- - Handles path segments with slashes (e.g., "fjell/order" matches key type "order")
153
-
@@ -1,120 +0,0 @@
1
- # Location Key Validation Update
2
-
3
- ## Summary
4
-
5
- Added automatic runtime validation to the `client-api` library that prevents location keys from being passed in the wrong order. This validation throws a clear, actionable error message instead of silently generating malformed URL paths.
6
-
7
- ## Problem Being Solved
8
-
9
- Previously, if location keys were passed in the wrong order (e.g., `[orderFormKey, orderKey]` instead of `[orderKey, orderFormKey]`), the library would silently generate a malformed URL path like:
10
- ```
11
- /orderForm/26693/fjell/order/26669/orderNoseShape
12
- ```
13
-
14
- Instead of the correct:
15
- ```
16
- /fjell/order/26669/orderForm/26693/orderNoseShape
17
- ```
18
-
19
- This resulted in 404 errors that were difficult to debug.
20
-
21
- ## Solution Implemented
22
-
23
- ### 1. Runtime Validation Function
24
-
25
- Added `validateLocationKeyOrder()` in `src/Utilities.ts` that:
26
- - Extracts location keys from the provided keys array
27
- - Builds a map of key types to their expected hierarchy position
28
- - Validates that location keys appear in strictly ascending order
29
- - Handles path segments with slashes (e.g., "fjell/order" correctly matches key type "order")
30
- - Throws a descriptive error if validation fails
31
-
32
- ### 2. Validation Error Message
33
-
34
- When keys are out of order, users get a clear error:
35
- ```
36
- Error: Location keys must be ordered from parent to child according to the entity hierarchy.
37
- Expected order based on pathNames: [fjell/order, orderForm, orderNoseShape].
38
- Received key types in order: [orderForm, order].
39
- Key "order" is out of order - it should appear earlier in the hierarchy.
40
- ```
41
-
42
- ### 3. Test Coverage
43
-
44
- Added comprehensive tests in `tests/Utilities.test.ts`:
45
- - ✅ `should generate path for nested entities with correct order`
46
- - ✅ `should generate path for collection access with location keys only`
47
- - ✅ `should throw error when location keys are in wrong order`
48
- - ✅ `should throw error with helpful message explaining the issue`
49
-
50
- ### 4. Documentation
51
-
52
- Created/updated documentation:
53
- - `LOCATION_KEY_ORDERING.md` - Complete guide on location key ordering with examples
54
- - Explains the validation, shows correct vs incorrect usage
55
- - Documents benefits and implementation details
56
-
57
- ## Benefits
58
-
59
- 1. **Fail Fast**: Errors caught at API call site, not after HTTP request
60
- 2. **Clear Error Messages**: Tells exactly what's wrong and the correct order
61
- 3. **Prevents Debugging Confusion**: No more hunting through logs for 404 causes
62
- 4. **Type-Safe + Runtime Safe**: TypeScript types prevent wrong order at compile time, runtime validation catches dynamic cases
63
- 5. **Zero Performance Cost for Correct Code**: Validation only runs when building paths
64
-
65
- ## Backwards Compatibility
66
-
67
- ✅ **Fully backwards compatible** - only throws errors for code that was already broken (passing keys in wrong order, which would have resulted in 404s)
68
-
69
- ## Files Changed
70
-
71
- 1. `src/Utilities.ts` - Added `validateLocationKeyOrder()` function and integrated it into `getPath()`
72
- 2. `tests/Utilities.test.ts` - Added 4 new tests for validation behavior
73
- 3. `LOCATION_KEY_ORDERING.md` - New comprehensive documentation
74
- 4. `LOCATION_KEY_VALIDATION_UPDATE.md` - This summary document
75
-
76
- ## Test Results
77
-
78
- All 302 tests pass across the entire test suite:
79
- ```
80
- Test Files 22 passed (22)
81
- Tests 302 passed (302)
82
- ```
83
-
84
- Coverage for `Utilities.ts`: **94.97%**
85
-
86
- ## Example Usage
87
-
88
- ### Before (Silent Failure)
89
- ```typescript
90
- const locations = [orderFormKey, orderKey]; // Wrong order!
91
- const items = await api.one({}, locations);
92
- // Result: 404 error with confusing path
93
- ```
94
-
95
- ### After (Clear Error)
96
- ```typescript
97
- const locations = [orderFormKey, orderKey]; // Wrong order!
98
- const items = await api.one({}, locations);
99
- // Throws immediately:
100
- // Error: Location keys must be ordered from parent to child...
101
- ```
102
-
103
- ### Correct Usage
104
- ```typescript
105
- const locations = [orderKey, orderFormKey]; // Correct order!
106
- const items = await api.one({}, locations);
107
- // Result: Success! ✅
108
- ```
109
-
110
- ## Recommendation for Your Project
111
-
112
- In your other project where you're experiencing the path ordering issue:
113
-
114
- 1. **Update the `@fjell/client-api` dependency** to get this validation
115
- 2. **Run your code** - the validation will immediately show you where keys are in wrong order
116
- 3. **Fix the order** based on the error messages
117
- 4. **Verify** the fix by checking that API calls succeed
118
-
119
- The validation will pinpoint exactly which API calls have keys in the wrong order and what the correct order should be.
120
-
package/MIGRATION_v3.md DELETED
@@ -1,231 +0,0 @@
1
- # Migration Guide: v4.4.x to v4.5.0
2
-
3
- ## Overview
4
-
5
- Version 4.5.0 adopts the Operations interface from `@fjell/core`, providing a consistent API across all Fjell packages.
6
-
7
- ## Breaking Changes Summary
8
-
9
- 1. **Core Operations Interface**: `ClientApi` now extends `Operations` from `@fjell/core`
10
- 2. **Create Method**: Changed signature to use `CreateOptions`
11
- 3. **Action Methods**: Parameter name changed from `body` to `params`
12
- 4. **Upsert Operation**: Added missing `upsert` method
13
-
14
- ## Dependency Updates
15
-
16
- Update your `package.json`:
17
-
18
- ```bash
19
- npm install @fjell/core@latest @fjell/client-api@latest
20
- ```
21
-
22
- ## Code Migration
23
-
24
- ### 1. Create Method
25
-
26
- The `create` method now uses `CreateOptions` instead of a simple `locations` parameter.
27
-
28
- #### Before (v4.4.x)
29
-
30
- ```typescript
31
- // With locations
32
- const item = await api.create(
33
- { name: 'Alice' },
34
- [{ kt: 'org', lk: 'org-123' }]
35
- );
36
-
37
- // Without locations
38
- const item = await api.create({ name: 'Alice' });
39
- ```
40
-
41
- #### After (v4.5.0)
42
-
43
- ```typescript
44
- // With locations - wrap in options object
45
- const item = await api.create(
46
- { name: 'Alice' },
47
- { locations: [{ kt: 'org', lk: 'org-123' }] }
48
- );
49
-
50
- // Without locations - omit options or pass undefined
51
- const item = await api.create({ name: 'Alice' });
52
-
53
- // NEW: With specific key
54
- const item = await api.create(
55
- { name: 'Alice' },
56
- { key: { kt: 'user', pk: 'custom-id' } }
57
- );
58
- ```
59
-
60
- ### 2. Action Methods
61
-
62
- The parameter name changed from `body` to `params` to match the core Operations interface. **Functionally, it's the same** - just a naming change.
63
-
64
- #### Before (v4.4.x)
65
-
66
- ```typescript
67
- const [item, affectedKeys] = await api.action(
68
- key,
69
- 'promote',
70
- { role: 'admin' } // called "body"
71
- );
72
-
73
- const [items, affectedKeys] = await api.allAction(
74
- 'archive',
75
- { reason: 'expired' }, // called "body"
76
- locations
77
- );
78
- ```
79
-
80
- #### After (v4.5.0)
81
-
82
- ```typescript
83
- // Same code - just know it's now called "params" internally
84
- const [item, affectedKeys] = await api.action(
85
- key,
86
- 'promote',
87
- { role: 'admin' } // now called "params"
88
- );
89
-
90
- const [items, affectedKeys] = await api.allAction(
91
- 'archive',
92
- { reason: 'expired' }, // now called "params"
93
- locations
94
- );
95
- ```
96
-
97
- ### 3. Upsert Operation (New)
98
-
99
- A new `upsert` operation is now available:
100
-
101
- ```typescript
102
- // Creates if doesn't exist, updates if it does
103
- const user = await api.upsert(
104
- { kt: 'user', pk: 'user-123' },
105
- { name: 'Alice', email: 'alice@example.com' }
106
- );
107
-
108
- // With locations (for contained items)
109
- const comment = await api.upsert(
110
- { kt: 'comment', pk: 'comment-456', loc: [{ kt: 'post', lk: 'post-123' }] },
111
- { text: 'Updated comment' },
112
- [{ kt: 'post', lk: 'post-123' }]
113
- );
114
- ```
115
-
116
- ### 4. Type Imports
117
-
118
- Import types from the appropriate package:
119
-
120
- #### Before (v4.4.x)
121
-
122
- ```typescript
123
- import { ClientApi } from '@fjell/client-api';
124
- // No OperationParams or AffectedKeys available
125
- ```
126
-
127
- #### After (v4.5.0)
128
-
129
- ```typescript
130
- import { ClientApi, OperationParams, AffectedKeys, CreateOptions } from '@fjell/client-api';
131
- // Or import directly from core
132
- import { Operations, OperationParams, AffectedKeys } from '@fjell/core';
133
- ```
134
-
135
- ## Type Compatibility
136
-
137
- The `ClientApi` interface is now fully compatible with the core `Operations` interface:
138
-
139
- ```typescript
140
- import type { Operations } from '@fjell/core';
141
- import type { ClientApi } from '@fjell/client-api';
142
-
143
- // These are now compatible
144
- function processItems(ops: Operations<User, 'user'>) {
145
- // Can pass either ClientApi or any other Operations implementation
146
- }
147
-
148
- const clientApi: ClientApi<User, 'user'> = ...;
149
- processItems(clientApi); // ✅ Works!
150
- ```
151
-
152
- ## Benefits of Migration
153
-
154
- ### 1. Consistent Interface
155
-
156
- All Fjell packages now share the same Operations interface:
157
-
158
- ```typescript
159
- // All implement the same Operations interface
160
- import { Operations } from '@fjell/lib';
161
- import { ClientApi } from '@fjell/client-api';
162
- import { Operations as FirestoreOps } from '@fjell/lib-firestore';
163
-
164
- // Can be used interchangeably
165
- function workWithOperations(ops: Operations<Item, string>) {
166
- // Works with any implementation
167
- }
168
- ```
169
-
170
- ### 2. Better Type Safety
171
-
172
- ```typescript
173
- import { OperationParams, AffectedKeys, CreateOptions } from '@fjell/core';
174
-
175
- // Strongly typed parameters
176
- const params: OperationParams = {
177
- status: 'active',
178
- limit: 10
179
- };
180
-
181
- // Type-safe create options
182
- const options: CreateOptions<'user'> = {
183
- key: { kt: 'user', pk: 'user-123' }
184
- };
185
- ```
186
-
187
- ### 3. Future Compatibility
188
-
189
- By adopting the core interface, your code will be compatible with future Fjell enhancements and new operation implementations.
190
-
191
- ## Troubleshooting
192
-
193
- ### TypeScript Errors
194
-
195
- If you see TypeScript errors after upgrading:
196
-
197
- 1. **Clear your TypeScript cache**: Delete `node_modules/.cache` and `dist/` directories
198
- 2. **Rebuild**: Run `npm run build`
199
- 3. **Update imports**: Ensure you're importing types from the correct packages
200
-
201
- ### Runtime Errors
202
-
203
- If you encounter runtime errors:
204
-
205
- 1. **Check create calls**: Wrap `locations` in options object: `{ locations: [...] }`
206
- 2. **Verify dependencies**: Ensure `@fjell/core` is at the latest version
207
- 3. **Clear node_modules**: Delete and reinstall if necessary
208
-
209
- ## Migration Checklist
210
-
211
- - [ ] Update package.json dependencies
212
- - [ ] Run `npm install`
213
- - [ ] Update `create` calls to use options object
214
- - [ ] Update any type imports
215
- - [ ] Test upsert operations if needed
216
- - [ ] Run tests: `npm test`
217
- - [ ] Build: `npm run build`
218
- - [ ] Check for TypeScript errors: `npm run lint`
219
-
220
- ## Questions or Issues?
221
-
222
- If you encounter any problems during migration:
223
-
224
- 1. Check the [API Reference](./docs/public/api-reference.md)
225
- 2. Review the [examples](./examples/)
226
- 3. File an issue on GitHub
227
-
228
- ## Previous Migrations
229
-
230
- - For migrations from older versions, see previous migration guides
231
-
package/vitest.config.ts DELETED
@@ -1,22 +0,0 @@
1
- /// <reference types="vitest" />
2
- import { defineConfig } from 'vitest/config'
3
-
4
- export default defineConfig({
5
- test: {
6
- environment: 'jsdom',
7
- setupFiles: ['./tests/setup.ts'],
8
- globals: true,
9
- testTimeout: 30000,
10
- coverage: {
11
- exclude: [
12
- 'build.js',
13
- 'docs/**',
14
- 'coverage/**',
15
- 'output/**',
16
- '**/*.config.*',
17
- '**/*.d.ts',
18
- 'dist/**',
19
- ]
20
- }
21
- },
22
- })