@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 CHANGED
@@ -887,7 +887,7 @@ var ObjectStackAdapter = class {
887
887
  try {
888
888
  const findParams = {
889
889
  ...params,
890
- $filter: { _id: String(id) },
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: { _id: String(id) },
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.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.1",
24
- "@object-ui/core": "3.1.1",
25
- "@object-ui/types": "3.1.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",
@@ -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={_id:...}&populate=...
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: { _id: '1', name: 'Test' } }),
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: [{ _id: '1', name: 'Order 1', customer: { _id: '2', name: 'Alice' } }],
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({ _id: '2', name: 'Alice' });
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: [{ _id: '1', name: 'Test' }], total: 1 });
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 _id filter and populate when $expand is present', async () => {
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: [{ _id: 'order-1', name: 'Order 1', customer: { _id: '2', name: 'Alice' } }],
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 _id
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({ _id: 'order-1' });
146
+ expect(parsedFilter).toEqual({ id: 'order-1' });
147
147
  expect(mockClient.data.get).not.toHaveBeenCalled();
148
- expect(result).toEqual({ _id: 'order-1', name: 'Order 1', customer: { _id: '2', name: 'Alice' } });
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: { _id: '1', name: 'Test' } });
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({ _id: '1', name: 'Test' });
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: [{ _id: '1', name: 'Order' }],
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 _id
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: { _id: String(id) },
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
- throw error;
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