Skip to content

Commit d80970e

Browse files
authored
Merge pull request #532 from objectstack-ai/copilot/fix-calendar-view-issue-yet-again
2 parents 309e596 + 27a4786 commit d80970e

File tree

3 files changed

+53
-12
lines changed

3 files changed

+53
-12
lines changed

apps/console/src/mocks/browser.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import { ObjectKernel } from '@objectstack/runtime';
1111
import { InMemoryDriver } from '@objectstack/driver-memory';
1212
import { setupWorker } from 'msw/browser';
13-
import appConfig from '../../objectstack.shared';
13+
import appConfig, { sharedConfig } from '../../objectstack.shared';
1414
import { createKernel } from './createKernel';
1515
import { createHandlers } from './handlers';
1616

@@ -42,8 +42,10 @@ export async function startMockServer() {
4242
// Create MSW handlers that match the response format of HonoServerPlugin
4343
// Include both /api/v1 and legacy /api paths so the ObjectStackClient can
4444
// reach the mock server regardless of which base URL it probes.
45-
const v1Handlers = createHandlers('/api/v1', kernel, driver);
46-
const legacyHandlers = createHandlers('/api', kernel, driver);
45+
// Pass sharedConfig (pre-defineStack) so handlers can enrich object metadata
46+
// with listViews that defineStack's Zod parse strips.
47+
const v1Handlers = createHandlers('/api/v1', kernel, driver, sharedConfig);
48+
const legacyHandlers = createHandlers('/api', kernel, driver, sharedConfig);
4749
const handlers = [...v1Handlers, ...legacyHandlers];
4850

4951
// Start MSW service worker

apps/console/src/mocks/handlers.ts

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,40 @@ import { ObjectKernel } from '@objectstack/runtime';
1212
import { InMemoryDriver } from '@objectstack/driver-memory';
1313
import { http, HttpResponse } from 'msw';
1414

15+
/** Minimal shape of the stack config used to enrich protocol responses. */
16+
interface StackConfig {
17+
objects?: Array<{ name: string; listViews?: Record<string, unknown> }>;
18+
}
19+
1520
/**
1621
* Create MSW request handlers for a given base URL.
1722
*
18-
* @param baseUrl - URL prefix, e.g. '/api/v1' (browser) or 'http://localhost:3000/api/v1' (node)
19-
* @param kernel - Bootstrapped ObjectKernel with protocol service
20-
* @param driver - InMemoryDriver for direct data access
23+
* @param baseUrl - URL prefix, e.g. '/api/v1' (browser) or 'http://localhost:3000/api/v1' (node)
24+
* @param kernel - Bootstrapped ObjectKernel with protocol service
25+
* @param driver - InMemoryDriver for direct data access
26+
* @param appConfig - Original stack config (used to enrich protocol responses with listViews)
2127
*/
22-
export function createHandlers(baseUrl: string, kernel: ObjectKernel, driver: InMemoryDriver) {
28+
export function createHandlers(baseUrl: string, kernel: ObjectKernel, driver: InMemoryDriver, appConfig?: StackConfig) {
2329
const protocol = kernel.getService('protocol') as any;
2430

31+
// Build a lookup of listViews by object name from the original config.
32+
// The runtime protocol strips listViews from object metadata, so we
33+
// re-attach them here to ensure the console can resolve named views.
34+
const listViewsByObject: Record<string, Record<string, unknown>> = {};
35+
if (appConfig?.objects) {
36+
for (const obj of appConfig.objects) {
37+
if (obj.listViews && Object.keys(obj.listViews).length > 0) {
38+
listViewsByObject[obj.name] = obj.listViews;
39+
}
40+
}
41+
}
42+
43+
/** Merge listViews from config into a single object metadata item. */
44+
function enrichObject(obj: any): any {
45+
const views = listViewsByObject[obj.name];
46+
return views ? { ...obj, listViews: { ...(obj.listViews || {}), ...views } } : obj;
47+
}
48+
2549
// Determine whether we're in a browser (relative paths, wildcard prefix)
2650
// or in Node.js tests (absolute URLs)
2751
const isBrowser = !baseUrl.startsWith('http');
@@ -56,11 +80,18 @@ export function createHandlers(baseUrl: string, kernel: ObjectKernel, driver: In
5680
http.get(`${prefix}${baseUrl}/meta/:type`, async ({ params }) => {
5781
const metadataType = params.type as string;
5882
const response = await protocol.getMetaItems({ type: metadataType });
83+
// Enrich object metadata with listViews from stack config
84+
if ((metadataType === 'object' || metadataType === 'objects') && response?.items) {
85+
response.items = response.items.map(enrichObject);
86+
}
5987
return HttpResponse.json(response, { status: 200 });
6088
}),
6189
http.get(`${prefix}${baseUrl}/metadata/:type`, async ({ params }) => {
6290
const metadataType = params.type as string;
6391
const response = await protocol.getMetaItems({ type: metadataType });
92+
if ((metadataType === 'object' || metadataType === 'objects') && response?.items) {
93+
response.items = response.items.map(enrichObject);
94+
}
6495
return HttpResponse.json(response, { status: 200 });
6596
}),
6697

@@ -71,7 +102,10 @@ export function createHandlers(baseUrl: string, kernel: ObjectKernel, driver: In
71102
type: params.type as string,
72103
name: params.name as string
73104
});
74-
const payload = (response && response.item) ? response.item : response;
105+
let payload = (response && response.item) ? response.item : response;
106+
if ((params.type === 'object' || params.type === 'objects') && payload?.name) {
107+
payload = enrichObject(payload);
108+
}
75109
return HttpResponse.json(payload || { error: 'Not found' }, { status: payload ? 200 : 404 });
76110
} catch (e) {
77111
return HttpResponse.json({ error: String(e) }, { status: 500 });
@@ -83,7 +117,10 @@ export function createHandlers(baseUrl: string, kernel: ObjectKernel, driver: In
83117
type: params.type as string,
84118
name: params.name as string
85119
});
86-
const payload = (response && response.item) ? response.item : response;
120+
let payload = (response && response.item) ? response.item : response;
121+
if ((params.type === 'object' || params.type === 'objects') && payload?.name) {
122+
payload = enrichObject(payload);
123+
}
87124
return HttpResponse.json(payload || { error: 'Not found' }, { status: payload ? 200 : 404 });
88125
} catch (e) {
89126
return HttpResponse.json({ error: String(e) }, { status: 500 });

apps/console/src/mocks/server.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import { ObjectKernel } from '@objectstack/runtime';
1111
import { InMemoryDriver } from '@objectstack/driver-memory';
1212
import { setupServer } from 'msw/node';
13-
import appConfig from '../../objectstack.shared';
13+
import appConfig, { sharedConfig } from '../../objectstack.shared';
1414
import { createKernel } from './createKernel';
1515
import { createHandlers } from './handlers';
1616

@@ -31,8 +31,10 @@ export async function startMockServer() {
3131
driver = result.driver;
3232

3333
// Create MSW handlers for both paths to ensure compatibility with client defaults
34-
const v1Handlers = createHandlers('http://localhost:3000/api/v1', kernel, driver);
35-
const legacyHandlers = createHandlers('http://localhost:3000/api', kernel, driver);
34+
// Pass sharedConfig (pre-defineStack) so handlers can enrich object metadata
35+
// with listViews that defineStack's Zod parse strips.
36+
const v1Handlers = createHandlers('http://localhost:3000/api/v1', kernel, driver, sharedConfig);
37+
const legacyHandlers = createHandlers('http://localhost:3000/api', kernel, driver, sharedConfig);
3638
const handlers = [...v1Handlers, ...legacyHandlers];
3739

3840
// Setup MSW server for Node.js environment

0 commit comments

Comments
 (0)