feat!: bundle only real defaults in app config - #156
Conversation
2e7684b to
0dacaba
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #156 +/- ##
=======================================
Coverage 99.54% 99.55%
=======================================
Files 100 100
Lines 666 671 +5
Branches 167 168 +1
=======================================
+ Hits 663 668 +5
Misses 2 2
Partials 1 1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
0dacaba to
2ce6c01
Compare
brian-smith-tcril
left a comment
There was a problem hiding this comment.
Looks great!
One non-blocking nit for consistency (inline comment written by claude) in how we're getting strings out of the config.
I specifically flagged not loving the "cast to string | undefined" pattern to claude and the result of the conversation is in that inline comment.
| // @ts-expect-error frontend-base ErrorPage declares message?: null but renders the prop as text. Remove when typing is fixed upstream. | ||
| message={intl.formatMessage(messages.errorMessage, { | ||
| supportEmail: getAppConfig(appId).INFO_EMAIL as string, | ||
| supportEmail: (getAppConfig(appId).INFO_EMAIL as string | undefined) ?? '', |
There was a problem hiding this comment.
Nit / readability — this is behavior-preserving and the cast is doing the right thing now that the key can actually be absent.
Dropping the bundled defaults turns "read a string out of app config" into a recurring shape. It shows up as a cast in four places:
src/catalog/CatalogPage.tsx:85src/course-about/CourseAboutPage.tsx:41src/home/components/courses-list/CoursesList.tsx:66src/course-about/course-sidebar/sidebar-social/utils.ts:29(COURSE_ABOUT_TWITTER_ACCOUNT)
...and a fifth time as a hand-written narrow in getLearningHomePageUrl:
const learningBaseUrl = getAppConfig(appId).LEARNING_BASE_URL;
return typeof learningBaseUrl === 'string' && learningBaseUrl
? `${learningBaseUrl}/course/${courseId}/home`
: null;One accessor would cover all five:
// src/config.ts
import { getAppConfig } from '@openedx/frontend-base';
import { appId } from '@src/constants';
export const getStringConfig = (key: string, fallback = ''): string => {
const value = getAppConfig(appId)[key];
return typeof value === 'string' ? value : fallback;
};The cast sites lose the cast and the parens:
supportEmail: getStringConfig('INFO_EMAIL'),and getLearningHomePageUrl keeps its null-when-unset contract without restating the narrow, since the '' fallback is falsy:
const learningBaseUrl = getStringConfig('LEARNING_BASE_URL');
return learningBaseUrl ? `${learningBaseUrl}/course/${courseId}/home` : null;Behavior is identical at all five sites either way — it's just one implementation of "string or fall back" instead of two spellings of it.
Entirely reasonable to skip if you'd rather not add an indirection for this.
There was a problem hiding this comment.
Actually, I love it. Thanks!
Every key an app declares in config is one commonAppConfig can never supply, so move the single genuine default, HOMEPAGE_COURSE_MAX, to App.defaultConfig and drop the other nine as no-ops or placeholders. BREAKING CHANGE: requires @openedx/frontend-base 2.0.0-alpha.4, the first release with App.defaultConfig, and an unset LEARNING_BASE_URL now renders no "View course" button. Co-Authored-By: Claude <noreply@anthropic.com>
Mechanical npm run lint:fix for a rule frontend-base 2.0 enables. Co-Authored-By: Claude <noreply@anthropic.com>
2ce6c01 to
3da71b2
Compare
Dropping the bundled defaults made "string or fall back" a recurring shape, spelled as a cast in five places and as a hand-written narrow in getLearningHomePageUrl. getStringConfig replaces both spellings. Co-Authored-By: Claude <noreply@anthropic.com>
|
🎉 This PR is included in version 1.0.0-alpha.2 🎉 The release is available on: Your semantic-release bot 📦🚀 |
Description
Every key an app declares in its own
configis a keycommonAppConfigcan never supply, since app config is the highest-precedence layer. Catalog declared ten, so values an operator set platform-wide throughMFE_CONFIGsilently lost to bundled defaults. OnlyHOMEPAGE_COURSE_MAX: 9is a real default, so it moves toApp.defaultConfig(frontend-base ADR 0017, added by openedx/frontend-base#298), which resolves belowcommonAppConfig; the other nine were no-ops against already-guarded reads or empty-string placeholders that now live at the point of use.LEARNING_BASE_URLis required config with no default that can work, sogetLearningHomePageUrlreturnsnullwhen it is unset and the course-about "View course" buttons are gated on a resolved URL. An operator who never set it now gets no button rather than one pointing at catalog's own origin.The peer dependency moves to
@openedx/frontend-base2.0.0-alpha.4, the first release carryingApp.defaultConfig. Lint,tsc, build, and all 387 tests pass against it. The second commit is a mechanicallint:fixfor a rule frontend-base 2.0 enables.LLM usage notice
Built with assistance from Claude.