@object-ui/data-objectstack 3.1.1 → 3.1.3
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/dist/index.cjs +1 -2
- package/dist/index.js +1 -2
- package/package.json +4 -4
- package/src/expand.test.ts +35 -13
- package/src/index.ts +5 -3
package/dist/index.cjs
CHANGED
|
@@ -887,7 +887,7 @@ var ObjectStackAdapter = class {
|
|
|
887
887
|
try {
|
|
888
888
|
const findParams = {
|
|
889
889
|
...params,
|
|
890
|
-
$filter: {
|
|
890
|
+
$filter: { id: String(id) },
|
|
891
891
|
$top: 1
|
|
892
892
|
};
|
|
893
893
|
const result = await this.rawFindWithPopulate(resource, findParams);
|
|
@@ -901,7 +901,6 @@ var ObjectStackAdapter = class {
|
|
|
901
901
|
if (error?.status === 404) {
|
|
902
902
|
return null;
|
|
903
903
|
}
|
|
904
|
-
throw error;
|
|
905
904
|
}
|
|
906
905
|
}
|
|
907
906
|
try {
|
package/dist/index.js
CHANGED
|
@@ -847,7 +847,7 @@ var ObjectStackAdapter = class {
|
|
|
847
847
|
try {
|
|
848
848
|
const findParams = {
|
|
849
849
|
...params,
|
|
850
|
-
$filter: {
|
|
850
|
+
$filter: { id: String(id) },
|
|
851
851
|
$top: 1
|
|
852
852
|
};
|
|
853
853
|
const result = await this.rawFindWithPopulate(resource, findParams);
|
|
@@ -861,7 +861,6 @@ var ObjectStackAdapter = class {
|
|
|
861
861
|
if (error?.status === 404) {
|
|
862
862
|
return null;
|
|
863
863
|
}
|
|
864
|
-
throw error;
|
|
865
864
|
}
|
|
866
865
|
}
|
|
867
866
|
try {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@object-ui/data-objectstack",
|
|
3
|
-
"version": "3.1.
|
|
3
|
+
"version": "3.1.3",
|
|
4
4
|
"description": "ObjectStack Data Adapter for Object UI",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,9 +20,9 @@
|
|
|
20
20
|
"README.md"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@objectstack/client": "^3.2.
|
|
24
|
-
"@object-ui/core": "3.1.
|
|
25
|
-
"@object-ui/types": "3.1.
|
|
23
|
+
"@objectstack/client": "^3.2.6",
|
|
24
|
+
"@object-ui/core": "3.1.3",
|
|
25
|
+
"@object-ui/types": "3.1.3"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"tsup": "^8.5.1",
|
package/src/expand.test.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { ObjectStackAdapter } from './index';
|
|
|
16
16
|
// The key scenarios:
|
|
17
17
|
// 1. find() with $expand → raw GET /api/v1/data/:object?populate=...
|
|
18
18
|
// 2. find() without $expand → client.data.find() (GET) as before
|
|
19
|
-
// 3. findOne() with $expand → raw GET /api/v1/data/:object?filter={
|
|
19
|
+
// 3. findOne() with $expand → raw GET /api/v1/data/:object?filter={id:...}&populate=...
|
|
20
20
|
// 4. findOne() without $expand → client.data.get() as before
|
|
21
21
|
|
|
22
22
|
describe('ObjectStackAdapter $expand support', () => {
|
|
@@ -42,7 +42,7 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
42
42
|
data: {
|
|
43
43
|
find: vi.fn().mockResolvedValue({ records: [], total: 0 }),
|
|
44
44
|
query: vi.fn().mockResolvedValue({ records: [], total: 0 }),
|
|
45
|
-
get: vi.fn().mockResolvedValue({ record: {
|
|
45
|
+
get: vi.fn().mockResolvedValue({ record: { id: '1', name: 'Test' } }),
|
|
46
46
|
},
|
|
47
47
|
connect: vi.fn().mockResolvedValue(undefined),
|
|
48
48
|
discover: vi.fn().mockResolvedValue({ status: 'ok' }),
|
|
@@ -58,7 +58,7 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
58
58
|
mockFetch.mockResolvedValue({
|
|
59
59
|
ok: true,
|
|
60
60
|
json: () => Promise.resolve({
|
|
61
|
-
records: [{
|
|
61
|
+
records: [{ id: '1', name: 'Order 1', customer: { id: '2', name: 'Alice' } }],
|
|
62
62
|
total: 1,
|
|
63
63
|
}),
|
|
64
64
|
});
|
|
@@ -76,7 +76,7 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
76
76
|
expect(fetchUrl).toContain('top=10');
|
|
77
77
|
expect(mockClient.data.find).not.toHaveBeenCalled();
|
|
78
78
|
expect(result.data).toHaveLength(1);
|
|
79
|
-
expect(result.data[0].customer).toEqual({
|
|
79
|
+
expect(result.data[0].customer).toEqual({ id: '2', name: 'Alice' });
|
|
80
80
|
});
|
|
81
81
|
|
|
82
82
|
it('should pass filters and sort as query params', async () => {
|
|
@@ -103,7 +103,7 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
103
103
|
});
|
|
104
104
|
|
|
105
105
|
it('should use data.find() when $expand is not present', async () => {
|
|
106
|
-
mockClient.data.find.mockResolvedValue({ records: [{
|
|
106
|
+
mockClient.data.find.mockResolvedValue({ records: [{ id: '1', name: 'Test' }], total: 1 });
|
|
107
107
|
|
|
108
108
|
const result = await adapter.find('order', { $top: 10 });
|
|
109
109
|
|
|
@@ -121,11 +121,11 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
describe('findOne() with $expand', () => {
|
|
124
|
-
it('should make a raw GET request with
|
|
124
|
+
it('should make a raw GET request with id filter and populate when $expand is present', async () => {
|
|
125
125
|
mockFetch.mockResolvedValue({
|
|
126
126
|
ok: true,
|
|
127
127
|
json: () => Promise.resolve({
|
|
128
|
-
records: [{
|
|
128
|
+
records: [{ id: 'order-1', name: 'Order 1', customer: { id: '2', name: 'Alice' } }],
|
|
129
129
|
}),
|
|
130
130
|
});
|
|
131
131
|
|
|
@@ -139,13 +139,13 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
139
139
|
expect(fetchUrl).toContain('populate=customer%2Caccount');
|
|
140
140
|
expect(fetchUrl).toContain('top=1');
|
|
141
141
|
expect(fetchUrl).toContain('filter=');
|
|
142
|
-
// Verify the filter contains
|
|
142
|
+
// Verify the filter contains id
|
|
143
143
|
const filterParam = new URL(fetchUrl).searchParams.get('filter');
|
|
144
144
|
expect(filterParam).toBeTruthy();
|
|
145
145
|
const parsedFilter = JSON.parse(filterParam!);
|
|
146
|
-
expect(parsedFilter).toEqual({
|
|
146
|
+
expect(parsedFilter).toEqual({ id: 'order-1' });
|
|
147
147
|
expect(mockClient.data.get).not.toHaveBeenCalled();
|
|
148
|
-
expect(result).toEqual({
|
|
148
|
+
expect(result).toEqual({ id: 'order-1', name: 'Order 1', customer: { id: '2', name: 'Alice' } });
|
|
149
149
|
});
|
|
150
150
|
|
|
151
151
|
it('should return null when raw request returns no records', async () => {
|
|
@@ -162,12 +162,12 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
it('should use data.get() when $expand is not present', async () => {
|
|
165
|
-
mockClient.data.get.mockResolvedValue({ record: {
|
|
165
|
+
mockClient.data.get.mockResolvedValue({ record: { id: '1', name: 'Test' } });
|
|
166
166
|
|
|
167
167
|
const result = await adapter.findOne('order', '1');
|
|
168
168
|
|
|
169
169
|
expect(mockClient.data.get).toHaveBeenCalledWith('order', '1');
|
|
170
|
-
expect(result).toEqual({
|
|
170
|
+
expect(result).toEqual({ id: '1', name: 'Test' });
|
|
171
171
|
});
|
|
172
172
|
|
|
173
173
|
it('should return null for 404 errors without $expand', async () => {
|
|
@@ -177,6 +177,28 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
177
177
|
|
|
178
178
|
expect(result).toBeNull();
|
|
179
179
|
});
|
|
180
|
+
|
|
181
|
+
it('should fall through to data.get() when $expand raw request fails with non-404 error', async () => {
|
|
182
|
+
// The raw populate request fails (e.g., server doesn't support the filter+populate API)
|
|
183
|
+
mockFetch.mockResolvedValue({
|
|
184
|
+
ok: false,
|
|
185
|
+
status: 500,
|
|
186
|
+
statusText: 'Internal Server Error',
|
|
187
|
+
json: () => Promise.resolve({ message: 'unsupported' }),
|
|
188
|
+
});
|
|
189
|
+
// But the direct data.get() call succeeds
|
|
190
|
+
mockClient.data.get.mockResolvedValue({ record: { id: 'order-1', name: 'Order 1' } });
|
|
191
|
+
|
|
192
|
+
const result = await adapter.findOne('order', 'order-1', {
|
|
193
|
+
$expand: ['customer'],
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
// Should have tried raw request first
|
|
197
|
+
expect(mockFetch).toHaveBeenCalled();
|
|
198
|
+
// Then fell through to data.get()
|
|
199
|
+
expect(mockClient.data.get).toHaveBeenCalledWith('order', 'order-1');
|
|
200
|
+
expect(result).toEqual({ id: 'order-1', name: 'Order 1' });
|
|
201
|
+
});
|
|
180
202
|
});
|
|
181
203
|
|
|
182
204
|
describe('raw request format', () => {
|
|
@@ -203,7 +225,7 @@ describe('ObjectStackAdapter $expand support', () => {
|
|
|
203
225
|
json: () => Promise.resolve({
|
|
204
226
|
success: true,
|
|
205
227
|
data: {
|
|
206
|
-
records: [{
|
|
228
|
+
records: [{ id: '1', name: 'Order' }],
|
|
207
229
|
total: 1,
|
|
208
230
|
},
|
|
209
231
|
}),
|
package/src/index.ts
CHANGED
|
@@ -278,14 +278,14 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
|
|
|
278
278
|
async findOne(resource: string, id: string | number, params?: QueryParams): Promise<T | null> {
|
|
279
279
|
await this.connect();
|
|
280
280
|
|
|
281
|
-
// When $expand is requested, use a raw GET request with a filter by
|
|
281
|
+
// When $expand is requested, use a raw GET request with a filter by id
|
|
282
282
|
// and populate. The installed server v3.0.10's getData() does not support
|
|
283
283
|
// expand/populate, so we route through findData which does.
|
|
284
284
|
if (params?.$expand && params.$expand.length > 0) {
|
|
285
285
|
try {
|
|
286
286
|
const findParams: QueryParams = {
|
|
287
287
|
...params,
|
|
288
|
-
$filter: {
|
|
288
|
+
$filter: { id: String(id) },
|
|
289
289
|
$top: 1,
|
|
290
290
|
};
|
|
291
291
|
const result = await this.rawFindWithPopulate(resource, findParams);
|
|
@@ -300,7 +300,9 @@ export class ObjectStackAdapter<T = unknown> implements DataSource<T> {
|
|
|
300
300
|
if ((error as Record<string, unknown>)?.status === 404) {
|
|
301
301
|
return null;
|
|
302
302
|
}
|
|
303
|
-
|
|
303
|
+
// Fall through to direct GET without $expand — some servers don't
|
|
304
|
+
// support the filter+populate API, so gracefully degrade to a
|
|
305
|
+
// simple data.get() call below rather than failing with "Record not found".
|
|
304
306
|
}
|
|
305
307
|
}
|
|
306
308
|
|