Remove double-pass defineStack hack, unify config composition flow#1024
Remove double-pass defineStack hack, unify config composition flow#1024
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Remove defineStack() validation pass from objectstack.config.ts and apps/console/objectstack.shared.ts that stripped runtime properties (listViews, actions) from objects, requiring a second composeStacks() call to restore them. - Use composed.apps in console shared config instead of manual spreading [...crmApps, ...(todoConfig.apps || []), ...(kitchenSinkConfig.apps || [])] - Use composed.reports instead of ...(crmConfig.reports || []) - Apply CRM navigation patch to composed output instead of pre-composing - Add 2 tests for conflict detection and prefixed naming pattern - Update ROADMAP.md with composeStacks responsibility split documentation Co-authored-by: hotlong <50353452+hotlong@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Removes the defineStack() validation + second composeStacks() “double-pass” workaround from the dev workspace and console shared config, standardizing on a single @object-ui/core composeStacks() flow so runtime fields (listViews, actions) remain attached to objects.
Changes:
- Simplified root
objectstack.config.tsto a single-passcomposeStacks()output passed intoAppPlugin(nodefineStack()). - Simplified
apps/console/objectstack.shared.tsto usecomposed.apps/composed.reports(with the CRM navigation patch applied post-composition) and removeddefineStack()+ second-pass restoration. - Added
composeStacks()unit tests forobjectConflict: 'error'and prefixed object-name coexistence; updated ROADMAP with the spec/core responsibility split.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| packages/core/src/utils/tests/compose-stacks.test.ts | Adds/extends coverage for conflict behavior and prefixed object naming scenarios. |
| objectstack.config.ts | Removes defineStack() and the second-pass restore; uses single composed config for AppPlugin. |
| apps/console/objectstack.shared.ts | Uses composed apps/reports consistently; drops validation + second-pass hack; keeps CRM nav patch. |
| ROADMAP.md | Documents the new single-pass flow and clarifies compose responsibility split (core vs spec). |
| it('should detect conflicting object names with objectConflict: "error"', () => { | ||
| // Simulates a scenario where two plugins define 'account' without prefixing | ||
| const crm = { | ||
| objects: [{ name: 'account', label: 'CRM Account', fields: {} }], | ||
| }; | ||
| const ks = { | ||
| objects: [{ name: 'account', label: 'KS Account', fields: {} }], | ||
| }; | ||
|
|
||
| expect(() => composeStacks([crm, ks], { objectConflict: 'error' })).toThrow( | ||
| 'duplicate object name "account"' | ||
| ); | ||
| }); | ||
|
|
There was a problem hiding this comment.
This conflict test duplicates the existing should throw on duplicate objects when objectConflict is "error" coverage earlier in the file. Consider removing it or adjusting it to cover a distinct case so the suite stays lean and easier to maintain.
| it('should detect conflicting object names with objectConflict: "error"', () => { | |
| // Simulates a scenario where two plugins define 'account' without prefixing | |
| const crm = { | |
| objects: [{ name: 'account', label: 'CRM Account', fields: {} }], | |
| }; | |
| const ks = { | |
| objects: [{ name: 'account', label: 'KS Account', fields: {} }], | |
| }; | |
| expect(() => composeStacks([crm, ks], { objectConflict: 'error' })).toThrow( | |
| 'duplicate object name "account"' | |
| ); | |
| }); |
| const dashboardIdx = crmApp.navigation.findIndex((n: any) => n.id === 'nav_dashboard'); | ||
| const insertIdx = dashboardIdx !== -1 ? dashboardIdx + 1 : 0; | ||
| crmApp.navigation.splice(insertIdx, 0, { | ||
| id: 'nav_sales_report', | ||
| type: 'url', | ||
| url: '/apps/crm_app/report/sales_performance_q1', | ||
| label: 'Sales Report', | ||
| icon: 'file-bar-chart' | ||
| }); |
There was a problem hiding this comment.
Indentation in this block is inconsistent with the surrounding 2-space indentation used in this file. Running the formatter (or adjusting indentation here) will improve readability and reduce noisy diffs in future edits.
| const dashboardIdx = crmApp.navigation.findIndex((n: any) => n.id === 'nav_dashboard'); | |
| const insertIdx = dashboardIdx !== -1 ? dashboardIdx + 1 : 0; | |
| crmApp.navigation.splice(insertIdx, 0, { | |
| id: 'nav_sales_report', | |
| type: 'url', | |
| url: '/apps/crm_app/report/sales_performance_q1', | |
| label: 'Sales Report', | |
| icon: 'file-bar-chart' | |
| }); | |
| const dashboardIdx = crmApp.navigation.findIndex((n: any) => n.id === 'nav_dashboard'); | |
| const insertIdx = dashboardIdx !== -1 ? dashboardIdx + 1 : 0; | |
| crmApp.navigation.splice(insertIdx, 0, { | |
| id: 'nav_sales_report', | |
| type: 'url', | |
| url: '/apps/crm_app/report/sales_performance_q1', | |
| label: 'Sales Report', | |
| icon: 'file-bar-chart', | |
| }); |
defineStack()Zod validation strips runtime properties (listViews,actions) from objects, forcing a secondcomposeStacks()pass to restore them. Console config also manually spreads apps/reports from individual sources instead of using composed output.Config simplification
objectstack.config.ts: RemovedefineStack()+ secondcomposeStacks()pass. SinglecomposeStacks()call produces final config directly.apps/console/objectstack.shared.ts: Same double-pass removal. Replace manual[...crmApps, ...(todoConfig.apps || []), ...]withcomposed.apps(CRM nav patch applied post-composition). Replace...(crmConfig.reports || [])with...(composed.reports || []).Before:
After:
Tests
objectConflict: 'error'catches duplicateaccount)account+ks_accountwithobjectConflict: 'error')Docs
composeStacksresponsibility split:@object-ui/corehandles runtime mapping (views→objects, actions→objects);@objectstack/spechandles protocol-level composition.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.