@openedx/frontend-base 1.0.0-alpha.0
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/LICENSE +661 -0
- package/README.md +112 -0
- package/config/babel/babel.config.js +28 -0
- package/config/config-helpers/createConfig.js +13 -0
- package/config/config-helpers/createLintConfig.js +16 -0
- package/config/config-helpers/getBaseConfig.js +12 -0
- package/config/defaultConfigPaths.js +35 -0
- package/config/eslint/base.eslint.config.js +113 -0
- package/config/index.js +12 -0
- package/config/jest/jest.config.js +30 -0
- package/config/tsconfig.json +32 -0
- package/config/types.js +25 -0
- package/config/webpack/common-config/all/getCodeRules.js +52 -0
- package/config/webpack/common-config/all/getFileLoaderRules.js +26 -0
- package/config/webpack/common-config/all/getIgnoreWarnings.js +14 -0
- package/config/webpack/common-config/all/getImageMinimizer.js +25 -0
- package/config/webpack/common-config/all/getStylesheetRule.js +112 -0
- package/config/webpack/common-config/dev/getDevServer.js +38 -0
- package/config/webpack/common-config/index.js +18 -0
- package/config/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
- package/config/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
- package/config/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
- package/config/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
- package/config/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
- package/config/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
- package/config/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
- package/config/webpack/types.js +2 -0
- package/config/webpack/utils/getLocalAliases.js +65 -0
- package/config/webpack/utils/getPublicPath.js +6 -0
- package/config/webpack/utils/getResolvedSiteConfigPath.js +32 -0
- package/config/webpack/utils/paragonUtils.js +138 -0
- package/config/webpack/webpack.config.build.js +80 -0
- package/config/webpack/webpack.config.dev.js +76 -0
- package/config/webpack/webpack.config.dev.shell.js +110 -0
- package/eslint.config.js +18 -0
- package/frontend-base.d.ts +8 -0
- package/index.ts +7 -0
- package/jest.config.js +7 -0
- package/openedx-frontend-base.tgz +0 -0
- package/package.json +149 -0
- package/runtime/analytics/MockAnalyticsService.js +71 -0
- package/runtime/analytics/SegmentAnalyticsService.js +243 -0
- package/runtime/analytics/index.ts +12 -0
- package/runtime/analytics/interface.js +145 -0
- package/runtime/auth/AxiosCsrfTokenService.js +60 -0
- package/runtime/auth/AxiosJwtAuthService.js +363 -0
- package/runtime/auth/AxiosJwtTokenService.js +134 -0
- package/runtime/auth/LocalForageCache.js +76 -0
- package/runtime/auth/MockAuthService.js +278 -0
- package/runtime/auth/index.ts +19 -0
- package/runtime/auth/interceptors/createCsrfTokenProviderInterceptor.js +36 -0
- package/runtime/auth/interceptors/createJwtTokenProviderInterceptor.js +37 -0
- package/runtime/auth/interceptors/createProcessAxiosRequestErrorInterceptor.js +20 -0
- package/runtime/auth/interceptors/createRetryInterceptor.js +74 -0
- package/runtime/auth/interface.js +309 -0
- package/runtime/auth/utils.js +105 -0
- package/runtime/babel.config.js +3 -0
- package/runtime/config/index.ts +295 -0
- package/runtime/constants.ts +68 -0
- package/runtime/i18n/index.js +118 -0
- package/runtime/i18n/injectIntlWithShim.jsx +48 -0
- package/runtime/i18n/lib.ts +272 -0
- package/runtime/index.ts +134 -0
- package/runtime/initialize.js +352 -0
- package/runtime/jest.config.js +32 -0
- package/runtime/logging/MockLoggingService.js +31 -0
- package/runtime/logging/NewRelicLoggingService.js +184 -0
- package/runtime/logging/index.ts +9 -0
- package/runtime/logging/interface.js +109 -0
- package/runtime/logging/types.ts +4 -0
- package/runtime/react/AuthenticatedPageRoute.jsx +43 -0
- package/runtime/react/CombinedAppProvider.tsx +46 -0
- package/runtime/react/CurrentAppContext.tsx +25 -0
- package/runtime/react/CurrentAppProvider.tsx +46 -0
- package/runtime/react/Divider.tsx +5 -0
- package/runtime/react/ErrorBoundary.jsx +47 -0
- package/runtime/react/ErrorPage.jsx +72 -0
- package/runtime/react/LoginRedirect.jsx +16 -0
- package/runtime/react/PageWrap.jsx +24 -0
- package/runtime/react/SiteContext.tsx +32 -0
- package/runtime/react/SiteProvider.tsx +78 -0
- package/runtime/react/hooks.ts +106 -0
- package/runtime/react/index.ts +19 -0
- package/runtime/routing/index.ts +1 -0
- package/runtime/routing/utils.ts +34 -0
- package/runtime/scripts/GoogleAnalyticsLoader.ts +59 -0
- package/runtime/scripts/index.ts +1 -0
- package/runtime/setupTest.js +49 -0
- package/runtime/slots/Slot.tsx +32 -0
- package/runtime/slots/SlotContext.tsx +8 -0
- package/runtime/slots/hooks.ts +35 -0
- package/runtime/slots/index.ts +7 -0
- package/runtime/slots/layout/DefaultSlotLayout.tsx +9 -0
- package/runtime/slots/layout/hooks.ts +65 -0
- package/runtime/slots/layout/index.ts +5 -0
- package/runtime/slots/layout/types.ts +45 -0
- package/runtime/slots/layout/utils.ts +14 -0
- package/runtime/slots/types.ts +23 -0
- package/runtime/slots/utils.ts +59 -0
- package/runtime/slots/widget/WidgetContext.tsx +9 -0
- package/runtime/slots/widget/WidgetProvider.tsx +30 -0
- package/runtime/slots/widget/hooks.ts +105 -0
- package/runtime/slots/widget/iframe/IFrameContentWrapper.messages.tsx +16 -0
- package/runtime/slots/widget/iframe/IFrameContentWrapper.tsx +84 -0
- package/runtime/slots/widget/iframe/IFrameWidget.tsx +59 -0
- package/runtime/slots/widget/iframe/constants.ts +19 -0
- package/runtime/slots/widget/iframe/hooks.ts +179 -0
- package/runtime/slots/widget/iframe/index.ts +6 -0
- package/runtime/slots/widget/iframe/types.ts +7 -0
- package/runtime/slots/widget/index.ts +6 -0
- package/runtime/slots/widget/types.ts +134 -0
- package/runtime/slots/widget/utils.tsx +201 -0
- package/runtime/subscriptions.ts +60 -0
- package/runtime/testing/index.ts +9 -0
- package/runtime/testing/initializeMockApp.ts +81 -0
- package/runtime/testing/mockMessages.ts +23 -0
- package/runtime/utils.js +178 -0
- package/shell/DefaultLayout.tsx +18 -0
- package/shell/DefaultMain.tsx +7 -0
- package/shell/Logo.tsx +28 -0
- package/shell/Shell.messages.ts +61 -0
- package/shell/Shell.tsx +18 -0
- package/shell/app.scss +149 -0
- package/shell/app.ts +24 -0
- package/shell/babel.config.js +3 -0
- package/shell/dev/devFooter/app.tsx +43 -0
- package/shell/dev/devFooter/index.ts +1 -0
- package/shell/dev/devHeader/BarContext.tsx +13 -0
- package/shell/dev/devHeader/BarLink.tsx +16 -0
- package/shell/dev/devHeader/BarProvider.tsx +25 -0
- package/shell/dev/devHeader/CoursesLink.tsx +16 -0
- package/shell/dev/devHeader/FooContext.tsx +13 -0
- package/shell/dev/devHeader/FooLink.tsx +16 -0
- package/shell/dev/devHeader/FooProvider.tsx +25 -0
- package/shell/dev/devHeader/app.tsx +53 -0
- package/shell/dev/devHeader/index.ts +1 -0
- package/shell/dev/devHeader/providers.tsx +11 -0
- package/shell/dev/devHome/HomePage.tsx +28 -0
- package/shell/dev/devHome/app.ts +18 -0
- package/shell/dev/devHome/i18n/index.ts +27 -0
- package/shell/dev/devHome/index.ts +1 -0
- package/shell/dev/devHome/messages.ts +11 -0
- package/shell/dev/devUser/app.tsx +24 -0
- package/shell/dev/devUser/index.ts +1 -0
- package/shell/dev/index.ts +5 -0
- package/shell/dev/slotShowcase/HorizontalSlotLayout.tsx +11 -0
- package/shell/dev/slotShowcase/LayoutWithOptions.tsx +17 -0
- package/shell/dev/slotShowcase/SlotShowcasePage.tsx +66 -0
- package/shell/dev/slotShowcase/WidgetWithOptions.tsx +11 -0
- package/shell/dev/slotShowcase/app.tsx +373 -0
- package/shell/dev/slotShowcase/index.ts +1 -0
- package/shell/footer/CenterLinks.tsx +11 -0
- package/shell/footer/CopyrightNotice.tsx +36 -0
- package/shell/footer/Footer.tsx +34 -0
- package/shell/footer/LabeledLinkColumn.tsx +19 -0
- package/shell/footer/LanguageMenu.tsx +35 -0
- package/shell/footer/LanguageMenuItem.tsx +23 -0
- package/shell/footer/LeftLinks.tsx +11 -0
- package/shell/footer/LegalNotices.tsx +17 -0
- package/shell/footer/PoweredBy.tsx +17 -0
- package/shell/footer/RevealLinks.tsx +43 -0
- package/shell/footer/RightLinks.tsx +11 -0
- package/shell/footer/app.tsx +73 -0
- package/shell/footer/data/api.ts +48 -0
- package/shell/footer/index.ts +2 -0
- package/shell/header/AuthenticatedMenu.tsx +32 -0
- package/shell/header/Header.tsx +17 -0
- package/shell/header/anonymous-menu/AnonymousMenu.tsx +14 -0
- package/shell/header/anonymous-menu/LoginButton.tsx +14 -0
- package/shell/header/anonymous-menu/RegisterButton.tsx +15 -0
- package/shell/header/app.tsx +142 -0
- package/shell/header/desktop/DesktopLayout.tsx +22 -0
- package/shell/header/desktop/PrimaryNavLinks.tsx +10 -0
- package/shell/header/desktop/SecondaryNavLinks.tsx +10 -0
- package/shell/header/index.ts +2 -0
- package/shell/header/mobile/MobileLayout.tsx +47 -0
- package/shell/header/mobile/MobileNavLinks.tsx +10 -0
- package/shell/i18n/index.ts +25 -0
- package/shell/index.ts +7 -0
- package/shell/jest.config.js +30 -0
- package/shell/menus/LinkMenuItem.tsx +64 -0
- package/shell/menus/NavDropdownMenuSlot.tsx +29 -0
- package/shell/menus/ProfileLinkMenuItem.tsx +33 -0
- package/shell/menus/data/utils.ts +19 -0
- package/shell/public/index.html +10 -0
- package/shell/router/createRouter.ts +17 -0
- package/shell/router/getAppRoutes.ts +21 -0
- package/shell/setupTest.js +48 -0
- package/shell/site.config.dev.tsx +49 -0
- package/shell/site.tsx +41 -0
- package/test-site/app.d.ts +15 -0
- package/test-site/dist/176.436443549ebb858db483.js +2 -0
- package/test-site/dist/176.436443549ebb858db483.js.map +1 -0
- package/test-site/dist/362.536eff787d2380fe246c.js +2 -0
- package/test-site/dist/362.536eff787d2380fe246c.js.map +1 -0
- package/test-site/dist/653.486966b108d224551296.js +2 -0
- package/test-site/dist/653.486966b108d224551296.js.map +1 -0
- package/test-site/dist/74e025d3fe9a7b7f8503054e2563b353.jpg +0 -0
- package/test-site/dist/806.323cf6496ad0a7fe73a7.js +3 -0
- package/test-site/dist/806.323cf6496ad0a7fe73a7.js.LICENSE.txt +106 -0
- package/test-site/dist/806.323cf6496ad0a7fe73a7.js.map +1 -0
- package/test-site/dist/95ec738c0b7faac5b5c9126794446bbd.svg +4 -0
- package/test-site/dist/app.612058b36c74787759ac.css +61 -0
- package/test-site/dist/app.612058b36c74787759ac.css.map +1 -0
- package/test-site/dist/app.612058b36c74787759ac.js +2 -0
- package/test-site/dist/app.612058b36c74787759ac.js.map +1 -0
- package/test-site/dist/cb28cdb1468c915e27e5cec9af64f22f.svg +1 -0
- package/test-site/dist/index.html +1 -0
- package/test-site/dist/report.html +39 -0
- package/test-site/dist/runtime.c7aeaf7b967496cb076f.js +2 -0
- package/test-site/dist/runtime.c7aeaf7b967496cb076f.js.map +1 -0
- package/test-site/eslint.config.js +12 -0
- package/test-site/package-lock.json +19226 -0
- package/test-site/package.json +29 -0
- package/test-site/public/index.html +10 -0
- package/test-site/site.config.build.tsx +27 -0
- package/test-site/site.config.dev.tsx +27 -0
- package/test-site/src/authenticated-page/AuthenticatedPage.tsx +18 -0
- package/test-site/src/authenticated-page/i18n/index.ts +27 -0
- package/test-site/src/authenticated-page/index.tsx +28 -0
- package/test-site/src/example-page/ExamplePage.tsx +79 -0
- package/test-site/src/example-page/Image.tsx +11 -0
- package/test-site/src/example-page/ParagonPreview.jsx +66 -0
- package/test-site/src/example-page/apple.jpg +0 -0
- package/test-site/src/example-page/apple.svg +1 -0
- package/test-site/src/example-page/index.ts +16 -0
- package/test-site/src/i18n/README.md +3 -0
- package/test-site/src/i18n/messages/frontend-app-sample/ar.json +4 -0
- package/test-site/src/i18n/messages/frontend-app-sample/eo.json +1 -0
- package/test-site/src/i18n/messages/frontend-app-sample/es_419.json +4 -0
- package/test-site/src/i18n/messages/frontend-component-emptylangs/ar.json +1 -0
- package/test-site/src/i18n/messages/frontend-component-singlelang/ar.json +3 -0
- package/test-site/src/iframe-widget/IframeWidget.tsx +14 -0
- package/test-site/src/iframe-widget/index.ts +16 -0
- package/test-site/src/index.tsx +3 -0
- package/test-site/src/messages.js +11 -0
- package/test-site/src/site.scss +11 -0
- package/test-site/tsconfig.json +14 -0
- package/tools/babel/babel.config.js +27 -0
- package/tools/babel.config.js +3 -0
- package/tools/cli/README.md +29 -0
- package/tools/cli/commands/pack.ts +9 -0
- package/tools/cli/commands/release.ts +27 -0
- package/tools/cli/commands/serve.ts +43 -0
- package/tools/cli/intl-imports.ts +274 -0
- package/tools/cli/openedx.ts +101 -0
- package/tools/cli/transifex-utils.ts +75 -0
- package/tools/cli/utils/ensureConfigFilenameOption.ts +40 -0
- package/tools/cli/utils/formatter.ts +10 -0
- package/tools/cli/utils/getResolvedConfigPath.ts +23 -0
- package/tools/cli/utils/prettyPrintTitle.ts +15 -0
- package/tools/cli/utils/printUsage.ts +53 -0
- package/tools/config-helpers/createConfig.ts +8 -0
- package/tools/config-helpers/createLintConfig.ts +14 -0
- package/tools/config-helpers/getBaseConfig.ts +11 -0
- package/tools/defaultConfigPaths.ts +30 -0
- package/tools/dist/babel/babel.config.js +28 -0
- package/tools/dist/cli/commands/pack.js +14 -0
- package/tools/dist/cli/commands/release.js +28 -0
- package/tools/dist/cli/commands/serve.js +44 -0
- package/tools/dist/cli/intl-imports.js +233 -0
- package/tools/dist/cli/openedx.js +100 -0
- package/tools/dist/cli/transifex-utils.js +68 -0
- package/tools/dist/cli/utils/ensureConfigFilenameOption.js +42 -0
- package/tools/dist/cli/utils/formatter.js +10 -0
- package/tools/dist/cli/utils/getResolvedConfigPath.js +28 -0
- package/tools/dist/cli/utils/prettyPrintTitle.js +17 -0
- package/tools/dist/cli/utils/printUsage.js +48 -0
- package/tools/dist/config-helpers/createConfig.js +13 -0
- package/tools/dist/config-helpers/createLintConfig.js +16 -0
- package/tools/dist/config-helpers/getBaseConfig.js +12 -0
- package/tools/dist/defaultConfigPaths.js +35 -0
- package/tools/dist/eslint/base.eslint.config.js +113 -0
- package/tools/dist/eslint.config.js +11 -0
- package/tools/dist/index.js +12 -0
- package/tools/dist/jest/jest.config.js +30 -0
- package/tools/dist/jest.config.js +20 -0
- package/tools/dist/types.js +25 -0
- package/tools/dist/typescript/tsconfig.json +32 -0
- package/tools/dist/webpack/common-config/all/getCodeRules.js +52 -0
- package/tools/dist/webpack/common-config/all/getFileLoaderRules.js +26 -0
- package/tools/dist/webpack/common-config/all/getIgnoreWarnings.js +14 -0
- package/tools/dist/webpack/common-config/all/getImageMinimizer.js +25 -0
- package/tools/dist/webpack/common-config/all/getStylesheetRule.js +112 -0
- package/tools/dist/webpack/common-config/dev/getDevServer.js +38 -0
- package/tools/dist/webpack/common-config/index.js +18 -0
- package/tools/dist/webpack/common-config/site/getHtmlWebpackPlugin.js +16 -0
- package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.js +91 -0
- package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/index.js +7 -0
- package/tools/dist/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +3 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.js +108 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/index.js +7 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.js +64 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.js +53 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/index.js +9 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.js +114 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.js +146 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.js +126 -0
- package/tools/dist/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.js +57 -0
- package/tools/dist/webpack/types.js +2 -0
- package/tools/dist/webpack/utils/getLocalAliases.js +65 -0
- package/tools/dist/webpack/utils/getPublicPath.js +6 -0
- package/tools/dist/webpack/utils/getResolvedSiteConfigPath.js +32 -0
- package/tools/dist/webpack/utils/paragonUtils.js +138 -0
- package/tools/dist/webpack/webpack.config.build.js +80 -0
- package/tools/dist/webpack/webpack.config.dev.js +76 -0
- package/tools/dist/webpack/webpack.config.dev.shell.js +110 -0
- package/tools/eslint/base.eslint.config.js +124 -0
- package/tools/eslint/modules.d.ts +5 -0
- package/tools/eslint.config.js +15 -0
- package/tools/index.ts +3 -0
- package/tools/jest/jest.config.js +30 -0
- package/tools/jest.config.js +19 -0
- package/tools/tsconfig.json +24 -0
- package/tools/types.ts +21 -0
- package/tools/typescript/tsconfig.json +32 -0
- package/tools/webpack/common-config/README.md +15 -0
- package/tools/webpack/common-config/all/getCodeRules.ts +51 -0
- package/tools/webpack/common-config/all/getFileLoaderRules.ts +23 -0
- package/tools/webpack/common-config/all/getIgnoreWarnings.ts +13 -0
- package/tools/webpack/common-config/all/getImageMinimizer.ts +26 -0
- package/tools/webpack/common-config/all/getStylesheetRule.ts +111 -0
- package/tools/webpack/common-config/dev/getDevServer.ts +35 -0
- package/tools/webpack/common-config/index.ts +6 -0
- package/tools/webpack/common-config/site/getHtmlWebpackPlugin.ts +11 -0
- package/tools/webpack/modules.d.ts +6 -0
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/HtmlWebpackNewRelicPlugin.ts +102 -0
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/LICENSE +21 -0
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/README.md +7 -0
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/index.js +3 -0
- package/tools/webpack/plugins/html-webpack-new-relic-plugin/test/fixtures/entry.js +1 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/ParagonWebpackPlugin.ts +134 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/index.ts +3 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/assetUtils.ts +71 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/htmlUtils.ts +72 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/index.ts +6 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/paragonStylesheetUtils.ts +131 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/scriptUtils.ts +144 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/stylesheetUtils.ts +106 -0
- package/tools/webpack/plugins/paragon-webpack-plugin/utils/tagUtils.ts +54 -0
- package/tools/webpack/types.ts +69 -0
- package/tools/webpack/utils/getLocalAliases.ts +65 -0
- package/tools/webpack/utils/getPublicPath.ts +3 -0
- package/tools/webpack/utils/getResolvedSiteConfigPath.ts +28 -0
- package/tools/webpack/utils/paragonUtils.ts +152 -0
- package/tools/webpack/webpack.config.build.ts +93 -0
- package/tools/webpack/webpack.config.dev.shell.ts +122 -0
- package/tools/webpack/webpack.config.dev.ts +90 -0
- package/tsconfig.json +23 -0
- package/types.ts +99 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* This Babel configuration file is for Jest. The Webpack build does not use Babel.
|
|
4
|
+
*/
|
|
5
|
+
module.exports = {
|
|
6
|
+
presets: [
|
|
7
|
+
[
|
|
8
|
+
require.resolve('@babel/preset-env'), {
|
|
9
|
+
targets: { node: 'current' },
|
|
10
|
+
},
|
|
11
|
+
],
|
|
12
|
+
[
|
|
13
|
+
require.resolve('@babel/preset-react'), {
|
|
14
|
+
runtime: 'automatic',
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
require.resolve('@babel/preset-typescript'),
|
|
18
|
+
],
|
|
19
|
+
env: {
|
|
20
|
+
i18n: {
|
|
21
|
+
plugins: [
|
|
22
|
+
[
|
|
23
|
+
'formatjs',
|
|
24
|
+
],
|
|
25
|
+
],
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = pack;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function pack() {
|
|
10
|
+
const destination = process.argv[2];
|
|
11
|
+
(0, child_process_1.execSync)('npm run release', { stdio: 'inherit' });
|
|
12
|
+
const { filename } = JSON.parse((0, child_process_1.execSync)('npm pack --json').toString())[0];
|
|
13
|
+
(0, child_process_1.execSync)(`npm --prefix ../${destination} install ${path_1.default.resolve(process.cwd(), filename)}`, { stdio: 'inherit' });
|
|
14
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = release;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const child_process_1 = require("child_process");
|
|
9
|
+
const fs_1 = require("fs");
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
function release() {
|
|
12
|
+
const tsconfigPath = path_1.default.resolve(process.cwd(), './tsconfig.build.json');
|
|
13
|
+
if (!(0, fs_1.existsSync)(tsconfigPath)) {
|
|
14
|
+
console.error(chalk_1.default.red('openedx release: the library must include a tsconfig.build.json. Aborting.'));
|
|
15
|
+
process.exit(1);
|
|
16
|
+
}
|
|
17
|
+
// Clean up our dist folder.
|
|
18
|
+
(0, fs_1.rmSync)(path_1.default.resolve(process.cwd(), 'dist'), { recursive: true, force: true });
|
|
19
|
+
(0, child_process_1.execSync)(`tsc --project ${path_1.default.resolve(process.cwd(), './tsconfig.build.json')}`, { stdio: 'inherit' });
|
|
20
|
+
// Copy all non JS/TS files from src into dist. This is so imports of our assets still work.
|
|
21
|
+
(0, child_process_1.execSync)(`rsync -aR src/**/* --exclude='*.tsx' --exclude='*.ts' --exclude='*.js' --exclude='*.jsx' dist/`);
|
|
22
|
+
// The above rsync command will put the files in dist/src - move them up a folder into dist,
|
|
23
|
+
// merging them into the compiled code there, and then delete dist/src.
|
|
24
|
+
if ((0, fs_1.existsSync)(path_1.default.resolve(process.cwd(), 'dist/src'))) {
|
|
25
|
+
(0, child_process_1.execSync)('cp -R dist/src/* dist');
|
|
26
|
+
(0, child_process_1.execSync)('rm -rf dist/src');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
7
|
+
const compression_1 = __importDefault(require("compression"));
|
|
8
|
+
const express_1 = __importDefault(require("express"));
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const path_1 = __importDefault(require("path"));
|
|
11
|
+
function isDirectoryEmpty(directoryPath) {
|
|
12
|
+
try {
|
|
13
|
+
const files = fs_1.default.readdirSync(directoryPath);
|
|
14
|
+
return files.length === 0;
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
if (error.code === 'ENOENT') {
|
|
18
|
+
// Directory does not exist, so treat it as empty.
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
throw error; // Throw the error for other cases
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const buildPath = path_1.default.join(process.cwd(), 'dist');
|
|
25
|
+
const buildPathIndex = path_1.default.join(buildPath, 'index.html');
|
|
26
|
+
if (isDirectoryEmpty(buildPath)) {
|
|
27
|
+
const formattedBuildCmd = chalk_1.default.bold.redBright('``npm run build``');
|
|
28
|
+
console.log(chalk_1.default.bold.red(`ERROR: No build found. Please run ${formattedBuildCmd} first.`));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
const app = (0, express_1.default)();
|
|
32
|
+
app.use((0, compression_1.default)());
|
|
33
|
+
app.use(express_1.default.static(buildPath));
|
|
34
|
+
app.use('*', (req, res) => {
|
|
35
|
+
res.sendFile(buildPathIndex);
|
|
36
|
+
});
|
|
37
|
+
// Fallback to standard example port if no PORT config is set.
|
|
38
|
+
const PORT = process.env.PORT ?? 8080;
|
|
39
|
+
app.listen(PORT, () => {
|
|
40
|
+
const formattedServedFile = chalk_1.default.bold.cyanBright(buildPathIndex);
|
|
41
|
+
const formattedPort = chalk_1.default.bold.cyanBright(PORT);
|
|
42
|
+
console.log(chalk_1.default.greenBright(`Serving ${formattedServedFile} on port ${formattedPort}...`));
|
|
43
|
+
});
|
|
44
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.main = main;
|
|
8
|
+
const scriptHelpDocument = `
|
|
9
|
+
NAME
|
|
10
|
+
intl-imports.js — Script to generate the src/i18n/index.js file that exports messages from all the languages for Micro-frontends.
|
|
11
|
+
|
|
12
|
+
SYNOPSIS
|
|
13
|
+
intl-imports.js [DIRECTORY ...]
|
|
14
|
+
|
|
15
|
+
DESCRIPTION
|
|
16
|
+
This script is intended to run after 'atlas' has pulled the files.
|
|
17
|
+
|
|
18
|
+
This expects to run inside a Micro-frontend root directory with the following structure:
|
|
19
|
+
|
|
20
|
+
frontend-app-learning $ tree src/i18n/
|
|
21
|
+
src/i18n/
|
|
22
|
+
├── index.js
|
|
23
|
+
└── messages
|
|
24
|
+
├── frontend-app-example
|
|
25
|
+
│ ├── ar.json
|
|
26
|
+
│ ├── es_419.json
|
|
27
|
+
│ └── zh_CN.json
|
|
28
|
+
├── frontend-component-footer
|
|
29
|
+
│ ├── ar.json
|
|
30
|
+
│ ├── es_419.json
|
|
31
|
+
│ └── zh_CN.json
|
|
32
|
+
└── frontend-component-header (empty directory)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
With the structure above it's expected to run with the following command in Makefile:
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
$ node_modules/.bin/intl-imports.js frontend-component-footer frontend-component-header frontend-app-example
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
It will generate two type of files:
|
|
43
|
+
|
|
44
|
+
- Main src/i18n/index.js which overrides the Micro-frontend provided with a sample output of:
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
import messagesFromFrontendComponentFooter from './messages/frontend-component-footer';
|
|
48
|
+
// Skipped import due to missing './messages/frontend-component-footer/index.js' likely due to empty translations.
|
|
49
|
+
import messagesFromFrontendAppExample from './messages/frontend-app-example';
|
|
50
|
+
|
|
51
|
+
export default [
|
|
52
|
+
messagesFromFrontendComponentFooter,
|
|
53
|
+
messagesFromFrontendAppExample,
|
|
54
|
+
];
|
|
55
|
+
"""
|
|
56
|
+
|
|
57
|
+
- Each sub-directory has src/i18n/messages/frontend-component-header/index.js which is imported by the main file.:
|
|
58
|
+
|
|
59
|
+
"""
|
|
60
|
+
import messagesOfArLanguage from './ar.json';
|
|
61
|
+
import messagesOfDeLanguage from './de.json';
|
|
62
|
+
import messagesOfEs419Language from './es_419.json';
|
|
63
|
+
export default {
|
|
64
|
+
'ar': messagesOfArLanguage,
|
|
65
|
+
'de': messagesOfDeLanguage,
|
|
66
|
+
'es-419': messagesOfEs419Language,
|
|
67
|
+
};
|
|
68
|
+
"""
|
|
69
|
+
`;
|
|
70
|
+
const fs_1 = __importDefault(require("fs"));
|
|
71
|
+
const lodash_camelcase_1 = __importDefault(require("lodash.camelcase"));
|
|
72
|
+
const path_1 = __importDefault(require("path"));
|
|
73
|
+
const loggingPrefix = path_1.default.basename(`${__filename}`); // the name of this JS file
|
|
74
|
+
// Header note for generated src/i18n/index.js file
|
|
75
|
+
const filesCodeGeneratorNoticeHeader = `// This file is generated by the openedx/frontend-base's "intl-import.js" script.
|
|
76
|
+
//
|
|
77
|
+
// Refer to the i18n documents in https://docs.openedx.org/en/latest/developers/references/i18n.html to update
|
|
78
|
+
// the file and use the Micro-frontend i18n pattern in new repositories.
|
|
79
|
+
//
|
|
80
|
+
`;
|
|
81
|
+
/**
|
|
82
|
+
* Create frontend-app-example/index.js file with proper imports.
|
|
83
|
+
*
|
|
84
|
+
* @param directory - a directory name containing .json files from Transifex e.g. "frontend-app-example".
|
|
85
|
+
* @param log - Mockable process.stdout.write
|
|
86
|
+
* @param writeFileSync - Mockable fs.writeFileSync
|
|
87
|
+
* @param i18nDir - Path to `src/i18n` directory
|
|
88
|
+
*
|
|
89
|
+
* @return object - An object containing directory name and whether its "index.js" file was successfully written.
|
|
90
|
+
*/
|
|
91
|
+
function generateSubdirectoryMessageFile({ directory, log, writeFileSync, i18nDir, }) {
|
|
92
|
+
const importLines = [];
|
|
93
|
+
const messagesLines = [];
|
|
94
|
+
const counter = { nonEmptyLanguages: 0 };
|
|
95
|
+
const messagesDir = `${i18nDir}/messages`; // The directory of Micro-frontend i18n messages
|
|
96
|
+
try {
|
|
97
|
+
const files = fs_1.default.readdirSync(`${messagesDir}/${directory}`, { withFileTypes: true });
|
|
98
|
+
files.sort(); // Sorting ensures a consistent generated `index.js` order of imports cross-platforms.
|
|
99
|
+
const jsonFiles = files.filter(file => file.isFile() && file.name.endsWith('.json'));
|
|
100
|
+
if (!jsonFiles.length) {
|
|
101
|
+
log(`${loggingPrefix}: Not creating '${directory}/index.js' because no .json translation files were found.\n`);
|
|
102
|
+
return {
|
|
103
|
+
directory,
|
|
104
|
+
isWritten: false,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
jsonFiles.forEach((file) => {
|
|
108
|
+
const filename = file.name;
|
|
109
|
+
// Gets `fr_CA` from `fr_CA.json`
|
|
110
|
+
const languageCode = filename.replace(/\.json$/, '');
|
|
111
|
+
// React-friendly language code fr_CA --> fr-ca
|
|
112
|
+
const reactIntlLanguageCode = languageCode.toLowerCase().replace(/_/g, '-');
|
|
113
|
+
// camelCase variable name
|
|
114
|
+
const messagesCamelCaseVar = (0, lodash_camelcase_1.default)(`messages_Of_${languageCode}_Language`);
|
|
115
|
+
const filePath = `${messagesDir}/${directory}/${filename}`;
|
|
116
|
+
try {
|
|
117
|
+
const entries = JSON.parse(fs_1.default.readFileSync(filePath, { encoding: 'utf8' }));
|
|
118
|
+
if (!Object.keys(entries).length) {
|
|
119
|
+
importLines.push(`// Note: Skipped empty '${filename}' messages file.`);
|
|
120
|
+
return; // Skip the language
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (e) {
|
|
124
|
+
importLines.push(`// Error: unable to parse '${filename}' messages file.`);
|
|
125
|
+
log(`${loggingPrefix}: NOTICE: Skipping '${directory}/${filename}' due to error: ${e}.\n`);
|
|
126
|
+
return; // Skip the language
|
|
127
|
+
}
|
|
128
|
+
counter.nonEmptyLanguages += 1;
|
|
129
|
+
importLines.push(`import ${messagesCamelCaseVar} from './${filename}';`);
|
|
130
|
+
messagesLines.splice(1, 0, ` '${reactIntlLanguageCode}': ${messagesCamelCaseVar},`);
|
|
131
|
+
});
|
|
132
|
+
if (counter.nonEmptyLanguages) {
|
|
133
|
+
// See the help message above for sample output.
|
|
134
|
+
const messagesFileContent = [
|
|
135
|
+
filesCodeGeneratorNoticeHeader,
|
|
136
|
+
importLines.join('\n'),
|
|
137
|
+
'\nexport default {',
|
|
138
|
+
messagesLines.join('\n'),
|
|
139
|
+
'};\n',
|
|
140
|
+
].join('\n');
|
|
141
|
+
writeFileSync(`${messagesDir}/${directory}/index.js`, messagesFileContent);
|
|
142
|
+
return {
|
|
143
|
+
directory,
|
|
144
|
+
isWritten: true,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
log(`${loggingPrefix}: Skipping '${directory}' because no languages were found.\n`);
|
|
148
|
+
}
|
|
149
|
+
catch (e) {
|
|
150
|
+
log(`${loggingPrefix}: NOTICE: Skipping '${directory}' due to error: ${e}.\n`);
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
directory,
|
|
154
|
+
isWritten: false,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Create main `src/i18n/index.js` messages import file.
|
|
159
|
+
*
|
|
160
|
+
*
|
|
161
|
+
* @param processedDirectories - List of directories with a boolean flag whether its "index.js" file is written
|
|
162
|
+
* The format is "[\{ directory: "frontend-component-example", isWritten: false \}, ...]"
|
|
163
|
+
* @param log - Mockable process.stdout.write
|
|
164
|
+
* @param writeFileSync - Mockable fs.writeFileSync
|
|
165
|
+
* @param i18nDir` - Path to `src/i18n` directory
|
|
166
|
+
*/
|
|
167
|
+
function generateMainMessagesFile({ processedDirectories, log, writeFileSync, i18nDir, }) {
|
|
168
|
+
const importLines = [];
|
|
169
|
+
const exportLines = [];
|
|
170
|
+
processedDirectories.forEach(processedDirectory => {
|
|
171
|
+
const { directory, isWritten } = processedDirectory;
|
|
172
|
+
if (isWritten) {
|
|
173
|
+
const moduleCamelCaseVariableName = (0, lodash_camelcase_1.default)(`messages_from_${directory}`);
|
|
174
|
+
importLines.push(`import ${moduleCamelCaseVariableName} from './messages/${directory}';`);
|
|
175
|
+
exportLines.push(` ${moduleCamelCaseVariableName},`);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
const skipMessage = `Skipped import due to missing '${directory}/index.js' likely due to empty translations.`;
|
|
179
|
+
importLines.push(`// ${skipMessage}.`);
|
|
180
|
+
log(`${loggingPrefix}: ${skipMessage}\n`);
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
// See the help message above for sample output.
|
|
184
|
+
const indexFileContent = [
|
|
185
|
+
filesCodeGeneratorNoticeHeader,
|
|
186
|
+
importLines.join('\n'),
|
|
187
|
+
'\nexport default [',
|
|
188
|
+
exportLines.join('\n'),
|
|
189
|
+
'];\n',
|
|
190
|
+
].join('\n');
|
|
191
|
+
writeFileSync(`${i18nDir}/index.js`, indexFileContent);
|
|
192
|
+
}
|
|
193
|
+
/*
|
|
194
|
+
* Main function of the file.
|
|
195
|
+
*/
|
|
196
|
+
function main({ directories, log, writeFileSync, pwd, }) {
|
|
197
|
+
const i18nDir = `${pwd}/src/i18n`; // The Micro-frontend i18n root directory
|
|
198
|
+
if (directories.includes('--help') || directories.includes('-h')) {
|
|
199
|
+
log(scriptHelpDocument);
|
|
200
|
+
}
|
|
201
|
+
else if (!directories.length) {
|
|
202
|
+
log(scriptHelpDocument);
|
|
203
|
+
log(`${loggingPrefix}: Error: A list of directories is required.\n`);
|
|
204
|
+
}
|
|
205
|
+
else if (!fs_1.default.existsSync(i18nDir) || !fs_1.default.lstatSync(i18nDir).isDirectory()) {
|
|
206
|
+
log(scriptHelpDocument);
|
|
207
|
+
log(`${loggingPrefix}: Error: src/i18n directory was not found.\n`);
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
// If we're here, we know that directories is an array, so cast it as one.
|
|
211
|
+
const processedDirectories = directories.map((directory) => generateSubdirectoryMessageFile({
|
|
212
|
+
directory,
|
|
213
|
+
log,
|
|
214
|
+
writeFileSync,
|
|
215
|
+
i18nDir,
|
|
216
|
+
}));
|
|
217
|
+
generateMainMessagesFile({
|
|
218
|
+
processedDirectories,
|
|
219
|
+
log,
|
|
220
|
+
writeFileSync,
|
|
221
|
+
i18nDir,
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
if (require.main === module) {
|
|
226
|
+
// Run the main() function if called from the command line.
|
|
227
|
+
main({
|
|
228
|
+
directories: process.argv.slice(2),
|
|
229
|
+
log: text => process.stdout.write(text),
|
|
230
|
+
writeFileSync: fs_1.default.writeFileSync,
|
|
231
|
+
pwd: process.env.PWD ?? '.',
|
|
232
|
+
});
|
|
233
|
+
}
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const types_1 = require("../types");
|
|
11
|
+
const pack_1 = __importDefault(require("./commands/pack"));
|
|
12
|
+
const release_1 = __importDefault(require("./commands/release"));
|
|
13
|
+
const ensureConfigFilenameOption_1 = require("./utils/ensureConfigFilenameOption");
|
|
14
|
+
const prettyPrintTitle_1 = __importDefault(require("./utils/prettyPrintTitle"));
|
|
15
|
+
const printUsage_1 = __importDefault(require("./utils/printUsage"));
|
|
16
|
+
// commandName is the third argument after node and 'openedx'
|
|
17
|
+
const commandName = process.argv[2];
|
|
18
|
+
// remove 'openedx' from process.argv to allow subcommands to read options properly
|
|
19
|
+
process.argv.splice(1, 1);
|
|
20
|
+
let version;
|
|
21
|
+
if ((0, fs_1.existsSync)(path_1.default.resolve(__dirname, '../../package.json'))) {
|
|
22
|
+
version = require('../../package.json').version;
|
|
23
|
+
}
|
|
24
|
+
else if ((0, fs_1.existsSync)(path_1.default.resolve(__dirname, '../../../package.json'))) {
|
|
25
|
+
version = require('../../../package.json').version;
|
|
26
|
+
}
|
|
27
|
+
(0, prettyPrintTitle_1.default)(`Open edX CLI v${version}`);
|
|
28
|
+
switch (commandName) {
|
|
29
|
+
case types_1.CommandTypes.RELEASE:
|
|
30
|
+
(0, release_1.default)();
|
|
31
|
+
break;
|
|
32
|
+
case types_1.CommandTypes.PACK:
|
|
33
|
+
if (process.argv[2] === undefined) {
|
|
34
|
+
console.log(chalk_1.default.red(`${chalk_1.default.bold.red(commandName)} command usage: specify a peer folder where the command should install the package:
|
|
35
|
+
|
|
36
|
+
npm run pack my-project`));
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
(0, pack_1.default)();
|
|
40
|
+
break;
|
|
41
|
+
case types_1.CommandTypes.LINT:
|
|
42
|
+
(0, ensureConfigFilenameOption_1.ensureConfigFilenameOption)(types_1.ConfigTypes.LINT, ['-c', '--config']);
|
|
43
|
+
require('.bin/eslint');
|
|
44
|
+
break;
|
|
45
|
+
case types_1.CommandTypes.TEST:
|
|
46
|
+
(0, ensureConfigFilenameOption_1.ensureConfigFilenameOption)(types_1.ConfigTypes.TEST, ['-c', '--config']);
|
|
47
|
+
require('jest/bin/jest');
|
|
48
|
+
break;
|
|
49
|
+
case types_1.CommandTypes.BUILD:
|
|
50
|
+
(0, ensureConfigFilenameOption_1.ensureConfigFilenameOption)(types_1.ConfigTypes.WEBPACK_BUILD, ['-c', '--config']);
|
|
51
|
+
require('webpack/bin/webpack');
|
|
52
|
+
break;
|
|
53
|
+
case types_1.CommandTypes.DEV:
|
|
54
|
+
(0, ensureConfigFilenameOption_1.ensureConfigFilenameOption)(types_1.ConfigTypes.WEBPACK_DEV, ['-c', '--config']);
|
|
55
|
+
require('webpack-dev-server/bin/webpack-dev-server');
|
|
56
|
+
break;
|
|
57
|
+
case types_1.CommandTypes.DEV_SHELL:
|
|
58
|
+
(0, ensureConfigFilenameOption_1.ensureConfigFilenameOption)(types_1.ConfigTypes.WEBPACK_DEV_SHELL, ['-c', '--config']);
|
|
59
|
+
require('webpack-dev-server/bin/webpack-dev-server');
|
|
60
|
+
break;
|
|
61
|
+
case types_1.CommandTypes.FORMAT_JS: {
|
|
62
|
+
/* The include option is used to specify which additional source folders to extract messages from.
|
|
63
|
+
* To extract more messages on other source folders use: --include=plugins --include=plugins2
|
|
64
|
+
* The intention use case is to allow extraction from the 'plugins' directory on 'frontend-app-authoring'.
|
|
65
|
+
* That plugins folder were kept outside the src folder to ensure they remain independent and
|
|
66
|
+
* can function without relying on the MFE environment's special features.
|
|
67
|
+
* This approach allows them to be packaged separately as NPM packages. */
|
|
68
|
+
const additionalSrcFolders = [];
|
|
69
|
+
process.argv.forEach((val, index) => {
|
|
70
|
+
if (val.startsWith('--include=')) {
|
|
71
|
+
additionalSrcFolders.push(val.split('=')[1]);
|
|
72
|
+
process.argv.splice(index, 1);
|
|
73
|
+
}
|
|
74
|
+
});
|
|
75
|
+
const srcFolders = ['src'].concat(additionalSrcFolders);
|
|
76
|
+
let srcFoldersString = srcFolders.join(',');
|
|
77
|
+
if (srcFolders.length > 1) {
|
|
78
|
+
srcFoldersString = `{${srcFoldersString}}`;
|
|
79
|
+
}
|
|
80
|
+
process.argv = process.argv.concat([
|
|
81
|
+
'--format', 'node_modules/@openedx/frontend-base/dist/tools/cli/utils/formatter.js',
|
|
82
|
+
'--ignore', `${srcFoldersString}/**/*.json`,
|
|
83
|
+
'--ignore', `${srcFoldersString}/**/*.d.ts`,
|
|
84
|
+
'--out-file', './temp/formatjs/Default.messages.json',
|
|
85
|
+
'--', `${srcFoldersString}/**/*.{j,t}s*`,
|
|
86
|
+
]);
|
|
87
|
+
require('@formatjs/cli/bin/formatjs');
|
|
88
|
+
break;
|
|
89
|
+
}
|
|
90
|
+
case types_1.CommandTypes.SERVE:
|
|
91
|
+
require('./commands/serve');
|
|
92
|
+
break;
|
|
93
|
+
case types_1.CommandTypes.HELP:
|
|
94
|
+
(0, printUsage_1.default)();
|
|
95
|
+
break;
|
|
96
|
+
default:
|
|
97
|
+
console.log(`The command ${chalk_1.default.bold(commandName)} doesn't exist.`);
|
|
98
|
+
console.log('');
|
|
99
|
+
(0, printUsage_1.default)();
|
|
100
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const glob_1 = __importDefault(require("glob"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
/*
|
|
11
|
+
* See the Makefile for how the required hash file is downloaded from Transifex.
|
|
12
|
+
*/
|
|
13
|
+
/*
|
|
14
|
+
* Expected input: a directory, possibly containing subdirectories, with .json files. Each .json
|
|
15
|
+
* file is an array of translation triplets (id, description, defaultMessage).
|
|
16
|
+
*
|
|
17
|
+
*
|
|
18
|
+
*/
|
|
19
|
+
function gatherJson(dir) {
|
|
20
|
+
const ret = [];
|
|
21
|
+
const files = glob_1.default.sync(`${dir}/**/*.json`);
|
|
22
|
+
files.forEach((filename) => {
|
|
23
|
+
const messages = JSON.parse(fs_1.default.readFileSync(filename, { encoding: 'utf8' }));
|
|
24
|
+
ret.push(...messages);
|
|
25
|
+
});
|
|
26
|
+
return ret;
|
|
27
|
+
}
|
|
28
|
+
// the hash file returns ids whose periods are "escaped" (sort of), like this:
|
|
29
|
+
// "key": "profile\\.sociallinks\\.social\\.links"
|
|
30
|
+
// so our regular messageIds won't match them out of the box
|
|
31
|
+
function escapeDots(messageId) {
|
|
32
|
+
return messageId.replace(/\./g, '\\.');
|
|
33
|
+
}
|
|
34
|
+
const jsonDir = process.argv[2];
|
|
35
|
+
const messageObjects = gatherJson(jsonDir);
|
|
36
|
+
if (messageObjects.length === 0) {
|
|
37
|
+
process.exitCode = 1;
|
|
38
|
+
throw new Error('Found no messages');
|
|
39
|
+
}
|
|
40
|
+
if (process.argv[3] === '--comments') { // prepare to handle the translator notes
|
|
41
|
+
const loggingPrefix = path_1.default.basename(`${__filename}`); // the name of this JS file
|
|
42
|
+
const bashScriptsPath = (process.argv[4] && process.argv[4] === '--v3-scripts-path'
|
|
43
|
+
? './node_modules/@edx/reactifex/bash_scripts'
|
|
44
|
+
: './node_modules/reactifex/bash_scripts');
|
|
45
|
+
const hashFile = `${bashScriptsPath}/hashmap.json`;
|
|
46
|
+
process.stdout.write(`${loggingPrefix}: reading hash file ${hashFile}\n`);
|
|
47
|
+
const messageInfo = JSON.parse(fs_1.default.readFileSync(hashFile, { encoding: 'utf8' }));
|
|
48
|
+
const outputFile = `${bashScriptsPath}/hashed_data.txt`;
|
|
49
|
+
process.stdout.write(`${loggingPrefix}: writing to output file ${outputFile}\n`);
|
|
50
|
+
fs_1.default.writeFileSync(outputFile, '');
|
|
51
|
+
messageObjects.forEach((message) => {
|
|
52
|
+
const transifexFormatId = escapeDots(message.id);
|
|
53
|
+
const info = messageInfo.find((mi) => mi.key === transifexFormatId);
|
|
54
|
+
if (info) {
|
|
55
|
+
fs_1.default.appendFileSync(outputFile, `${info.string_hash}|${message.description}\n`);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
process.stdout.write(`${loggingPrefix}: string ${message.id} does not yet exist on transifex!\n`);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
const output = {};
|
|
64
|
+
messageObjects.forEach((message) => {
|
|
65
|
+
output[message.id] = message.defaultMessage;
|
|
66
|
+
});
|
|
67
|
+
fs_1.default.writeFileSync(process.argv[3], JSON.stringify(output, null, 2));
|
|
68
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ensureConfigFilenameOption = ensureConfigFilenameOption;
|
|
7
|
+
const path_1 = __importDefault(require("path"));
|
|
8
|
+
const getResolvedConfigPath_1 = __importDefault(require("./getResolvedConfigPath"));
|
|
9
|
+
function ensureConfigFilenameOption(configType, keys) {
|
|
10
|
+
let configFileName = null;
|
|
11
|
+
let fileNameIndex = null;
|
|
12
|
+
for (const key of keys) {
|
|
13
|
+
const index = process.argv.indexOf(key);
|
|
14
|
+
if (index !== -1) {
|
|
15
|
+
fileNameIndex = index + 1;
|
|
16
|
+
if (process.argv.length > fileNameIndex) {
|
|
17
|
+
configFileName = process.argv[fileNameIndex];
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
console.error(`You must specify a config filename as the next argument when using the ${key} flag. Aborting.`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
let customConfigFilePath = null;
|
|
26
|
+
if (configFileName !== null) {
|
|
27
|
+
customConfigFilePath = path_1.default.resolve(process.cwd(), configFileName);
|
|
28
|
+
}
|
|
29
|
+
const resolvedConfigPath = (0, getResolvedConfigPath_1.default)(customConfigFilePath, configType);
|
|
30
|
+
if (resolvedConfigPath === null) {
|
|
31
|
+
console.error(`No valid config file was found. Did you forget to create a config file? You may specify a custom path with the ${keys.join(' or ')} flag(s).`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
// If there wasn't a config flag on the command line, add one.
|
|
35
|
+
if (fileNameIndex === null) {
|
|
36
|
+
process.argv.push(keys[0]);
|
|
37
|
+
process.argv.push(resolvedConfigPath);
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
process.argv[fileNameIndex] = resolvedConfigPath;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.format = (messages) => {
|
|
4
|
+
const results = Object.entries(messages).map(([id, message]) => ({
|
|
5
|
+
id,
|
|
6
|
+
defaultMessage: message.defaultMessage,
|
|
7
|
+
description: message.description,
|
|
8
|
+
}));
|
|
9
|
+
return results;
|
|
10
|
+
};
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = getResolvedConfigPath;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const defaultConfigPaths_1 = require("../../defaultConfigPaths");
|
|
9
|
+
function getResolvedConfigPath(customConfigPath, configType) {
|
|
10
|
+
const configPaths = defaultConfigPaths_1.defaultConfigPaths[configType];
|
|
11
|
+
if (customConfigPath !== null) {
|
|
12
|
+
if (fs_1.default.existsSync(customConfigPath)) {
|
|
13
|
+
return customConfigPath;
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
console.error(`The custom config file at ${customConfigPath} does not exist. Aborting.`);
|
|
17
|
+
return null;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
else {
|
|
21
|
+
for (const configPath of configPaths) {
|
|
22
|
+
if (fs_1.default.existsSync(configPath)) {
|
|
23
|
+
return configPath;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = prettyPrintTitle;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const gradient_string_1 = __importDefault(require("gradient-string"));
|
|
9
|
+
function prettyPrintTitle(title) {
|
|
10
|
+
const openedxGradient = (0, gradient_string_1.default)(['#B82669', '#22358C']);
|
|
11
|
+
const borderedTitle = `█ ${title} █`;
|
|
12
|
+
const whitespace = Array.from({ length: borderedTitle.length }, () => '█').join('');
|
|
13
|
+
console.log(chalk_1.default.bgWhite(openedxGradient(whitespace)));
|
|
14
|
+
console.log(chalk_1.default.bold.bgWhite(openedxGradient(borderedTitle)));
|
|
15
|
+
console.log(chalk_1.default.bgWhite(openedxGradient(whitespace)));
|
|
16
|
+
console.log('');
|
|
17
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.default = printUsage;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
function printUsage() {
|
|
9
|
+
console.log('CLI Usage:\n');
|
|
10
|
+
console.group();
|
|
11
|
+
console.log('openedx <command> <options>\n');
|
|
12
|
+
console.groupEnd();
|
|
13
|
+
console.log('Commands:\n');
|
|
14
|
+
console.group();
|
|
15
|
+
console.log(`${chalk_1.default.bold('release')}\n`);
|
|
16
|
+
console.group();
|
|
17
|
+
console.log(`Compile source code for release as a library. Compiled code is put into the dist folder.\n`);
|
|
18
|
+
console.groupEnd();
|
|
19
|
+
console.log(`${chalk_1.default.bold('pack')} <peer folder>\n`);
|
|
20
|
+
console.group();
|
|
21
|
+
console.log(`Package the dist folder as an NPM-compatible .tgz file suitable for use with npm install, then install it in the specified peer folder. The folder is assumed to be a peer of this repository, do not include a path.\n`);
|
|
22
|
+
console.groupEnd();
|
|
23
|
+
console.log(`${chalk_1.default.bold('lint')} <eslint options>\n`);
|
|
24
|
+
console.group();
|
|
25
|
+
console.log(`Runs ESLint on the source code. Requires an ${chalk_1.default.bold('eslint.config.js')} file.\n`);
|
|
26
|
+
console.groupEnd();
|
|
27
|
+
console.log(`${chalk_1.default.bold('test')} <jest options>\n`);
|
|
28
|
+
console.group();
|
|
29
|
+
console.log(`Runs Jest on the source code test suite. Requires a ${chalk_1.default.bold('jest.config.js')} file.\n`);
|
|
30
|
+
console.groupEnd();
|
|
31
|
+
console.log(`${chalk_1.default.bold('build')}\n`);
|
|
32
|
+
console.group();
|
|
33
|
+
console.log(`Compiles the source code for deployment as a frontend site. Requires a ${chalk_1.default.bold('site.config.build.tsx')} file.\n`);
|
|
34
|
+
console.groupEnd();
|
|
35
|
+
console.log(`${chalk_1.default.bold('dev')}\n`);
|
|
36
|
+
console.group();
|
|
37
|
+
console.log(`Compiles the source code and serves it in Webpack dev server as a frontend site. Requires a ${chalk_1.default.bold('site.config.dev.tsx')} file.\n`);
|
|
38
|
+
console.groupEnd();
|
|
39
|
+
console.log(`${chalk_1.default.bold('formatjs')}\n`);
|
|
40
|
+
console.group();
|
|
41
|
+
console.log(`Runs formatjs on the source code to extract internationalization messages.\n`);
|
|
42
|
+
console.groupEnd();
|
|
43
|
+
console.log(`${chalk_1.default.bold('serve')}\n`);
|
|
44
|
+
console.group();
|
|
45
|
+
console.log(`Serves the dist folder with an express server. Used to locally test production assets.\n`);
|
|
46
|
+
console.groupEnd();
|
|
47
|
+
console.groupEnd();
|
|
48
|
+
}
|