Skip to content

Commit 15ff2e6

Browse files
Copilothotlong
andcommitted
fix: re-merge listViews after defineStack strips them from objects
Root cause: defineStack() validates config through Zod schemas which strip non-standard properties like listViews from objects. The mergeViewsIntoObjects() call in objectstack.shared.ts was being undone by the subsequent defineStack(). Fix: Apply defineStack() first for validation, then re-merge views from the raw config into the validated objects. Applied to both: - apps/console/objectstack.shared.ts (MSW/browser mode) - objectstack.config.ts (server mode) Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
1 parent a436d40 commit 15ff2e6

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

apps/console/objectstack.shared.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,4 +142,11 @@ export const sharedConfig = {
142142
]
143143
};
144144

145-
export default defineStack(sharedConfig as Parameters<typeof defineStack>[0]);
145+
// defineStack() validates the config but strips non-standard properties like
146+
// listViews from objects. Re-merge listViews after validation so the runtime
147+
// protocol serves objects with their view definitions (calendar, kanban, etc.).
148+
const validated = defineStack(sharedConfig as Parameters<typeof defineStack>[0]);
149+
export default {
150+
...validated,
151+
objects: mergeViewsIntoObjects(validated.objects || [], allConfigs),
152+
};

objectstack.config.ts

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,36 @@ const baseObjects = [
3434
...(kitchenSink.objects || []),
3535
];
3636

37+
// Collect all example configs for view merging
38+
const allConfigs = [crm, todo, kitchenSink];
39+
40+
// ---------------------------------------------------------------------------
41+
// Merge stack-level views into object definitions.
42+
// defineStack() strips non-standard properties like listViews from objects.
43+
// Re-merge listViews after validation so the runtime protocol serves objects
44+
// with their view definitions (calendar, kanban, etc.).
45+
// ---------------------------------------------------------------------------
46+
function mergeViewsIntoObjects(objects: any[], configs: any[]): any[] {
47+
const viewsByObject: Record<string, Record<string, any>> = {};
48+
for (const config of configs) {
49+
if (!Array.isArray(config.views)) continue;
50+
for (const view of config.views) {
51+
if (!view.listViews) continue;
52+
for (const [viewName, listView] of Object.entries(view.listViews as Record<string, any>)) {
53+
const objectName = listView?.data?.object;
54+
if (!objectName) continue;
55+
if (!viewsByObject[objectName]) viewsByObject[objectName] = {};
56+
viewsByObject[objectName][viewName] = listView;
57+
}
58+
}
59+
}
60+
return objects.map((obj: any) => {
61+
const views = viewsByObject[obj.name];
62+
if (!views) return obj;
63+
return { ...obj, listViews: { ...(obj.listViews || {}), ...views } };
64+
});
65+
}
66+
3767
// Merge all example configs into a single app bundle for AppPlugin
3868
const mergedApp = defineStack({
3969
manifest: {
@@ -49,6 +79,11 @@ const mergedApp = defineStack({
4979
],
5080
},
5181
objects: baseObjects,
82+
views: [
83+
...(crm.views || []),
84+
...(todo.views || []),
85+
...(kitchenSink.views || []),
86+
],
5287
apps: [
5388
...(crm.apps || []),
5489
...(todo.apps || []),
@@ -69,14 +104,20 @@ const mergedApp = defineStack({
69104
],
70105
} as any);
71106

107+
// Re-merge listViews that defineStack stripped from objects
108+
const mergedAppWithViews = {
109+
...mergedApp,
110+
objects: mergeViewsIntoObjects(mergedApp.objects || [], allConfigs),
111+
};
112+
72113
// Export only plugins — no top-level objects/manifest/apps.
73114
// The CLI auto-creates an AppPlugin from the config if it detects objects/manifest/apps,
74115
// which would conflict with our explicit AppPlugin and skip seed data loading.
75116
export default {
76117
plugins: [
77118
new ObjectQLPlugin(),
78119
new DriverPlugin(new InMemoryDriver()),
79-
new AppPlugin(mergedApp),
120+
new AppPlugin(mergedAppWithViews),
80121
new HonoServerPlugin({ port: 3000 }),
81122
new ConsolePlugin(),
82123
],

0 commit comments

Comments
 (0)