@openedx/frontend-base 1.0.0-alpha.21 → 1.0.0-alpha.23
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/dist/runtime/config/index.d.ts +8 -0
- package/dist/runtime/config/index.js +19 -0
- package/dist/runtime/config/index.js.map +1 -1
- package/dist/runtime/i18n/index.d.ts +1 -1
- package/dist/runtime/i18n/index.js +1 -1
- package/dist/runtime/i18n/index.js.map +1 -1
- package/dist/runtime/i18n/lib.d.ts +0 -6
- package/dist/runtime/i18n/lib.js +0 -13
- package/dist/runtime/i18n/lib.js.map +1 -1
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/index.js.map +1 -1
- package/dist/shell/dev/devHome/app.js +0 -2
- package/dist/shell/dev/devHome/app.js.map +1 -1
- package/dist/shell/dev/slotShowcase/SlotShowcase.scss +50 -0
- package/dist/shell/header/Header.js +2 -2
- package/dist/shell/header/Header.js.map +1 -1
- package/dist/shell/header/app.js +13 -1
- package/dist/shell/header/app.js.map +1 -1
- package/dist/shell/header/constants.d.ts +4 -0
- package/dist/shell/header/constants.js +5 -0
- package/dist/shell/header/constants.js.map +1 -0
- package/dist/shell/header/course-navigation-bar/CourseTabsNavigation.d.ts +3 -0
- package/dist/shell/header/course-navigation-bar/CourseTabsNavigation.js +57 -0
- package/dist/shell/header/course-navigation-bar/CourseTabsNavigation.js.map +1 -0
- package/dist/shell/header/course-navigation-bar/course-tabs-navigation.scss +7 -0
- package/dist/shell/header/course-navigation-bar/data/service.d.ts +9 -0
- package/dist/shell/header/course-navigation-bar/data/service.js +27 -0
- package/dist/shell/header/course-navigation-bar/data/service.js.map +1 -0
- package/dist/shell/header/course-navigation-bar/messages.d.ts +8 -0
- package/dist/shell/header/course-navigation-bar/messages.js +10 -0
- package/dist/shell/header/course-navigation-bar/messages.js.map +1 -0
- package/dist/shell/header/course-navigation-bar/utils.d.ts +2 -0
- package/dist/shell/header/course-navigation-bar/utils.js +25 -0
- package/dist/shell/header/course-navigation-bar/utils.js.map +1 -0
- package/dist/shell/site.js +1 -3
- package/dist/shell/site.js.map +1 -1
- package/dist/tools/cli/commands/translations.d.ts +2 -0
- package/dist/tools/cli/commands/translations.js +20 -0
- package/dist/tools/cli/openedx.js +6 -0
- package/dist/tools/cli/utils/printUsage.js +8 -0
- package/dist/tools/cli/utils/translations/index.d.ts +2 -0
- package/dist/tools/cli/utils/translations/index.js +7 -0
- package/dist/tools/cli/utils/translations/messagesObject.d.ts +26 -0
- package/dist/tools/cli/utils/translations/messagesObject.js +66 -0
- package/dist/tools/cli/utils/translations/prepare.d.ts +5 -0
- package/dist/tools/cli/utils/translations/prepare.js +98 -0
- package/dist/tools/cli/utils/translations/pull.d.ts +6 -0
- package/dist/tools/cli/utils/translations/pull.js +102 -0
- package/dist/tools/types.d.ts +2 -0
- package/dist/tools/types.js +2 -0
- package/dist/tools/webpack/common-config/index.d.ts +1 -0
- package/dist/tools/webpack/common-config/index.js +3 -1
- package/dist/tools/webpack/common-config/site/getI18nMessagesFallbackPlugin/emptyI18n.d.ts +2 -0
- package/dist/tools/webpack/common-config/site/getI18nMessagesFallbackPlugin/emptyI18n.js +3 -0
- package/dist/tools/webpack/common-config/site/getI18nMessagesFallbackPlugin/index.d.ts +2 -0
- package/dist/tools/webpack/common-config/site/getI18nMessagesFallbackPlugin/index.js +26 -0
- package/dist/tools/webpack/utils/getResolvedSiteI18nPath.d.ts +1 -0
- package/dist/tools/webpack/utils/getResolvedSiteI18nPath.js +25 -0
- package/dist/tools/webpack/webpack.config.build.js +4 -0
- package/dist/tools/webpack/webpack.config.dev.js +4 -0
- package/dist/tools/webpack/webpack.config.dev.shell.js +3 -0
- package/dist/types.d.ts +2 -1
- package/dist/types.js.map +1 -1
- package/package.json +13 -7
- package/dist/shell/dev/devHome/i18n/index.d.ts +0 -27
- package/dist/shell/dev/devHome/i18n/index.js +0 -28
- package/dist/shell/dev/devHome/i18n/index.js.map +0 -1
- package/dist/shell/i18n/index.d.ts +0 -25
- package/dist/shell/i18n/index.js +0 -26
- package/dist/shell/i18n/index.js.map +0 -1
- package/dist/tools/cli/intl-imports.d.ts +0 -7
- package/dist/tools/cli/intl-imports.js +0 -233
- package/dist/tools/cli/intl-imports.test.d.ts +0 -1
- package/dist/tools/cli/intl-imports.test.js +0 -146
- package/dist/tools/cli/transifex-utils.d.ts +0 -2
- package/dist/tools/cli/transifex-utils.js +0 -68
- package/dist/tools/webpack/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.d.ts +0 -1
- package/dist/tools/webpack/plugins/html-webpack-new-relic-plugin/test/HtmlWebpackNewRelicPlugin.test.js +0 -66
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { getSiteConfig, getAuthenticatedHttpClient, camelCaseObject } from '../../../../runtime';
|
|
11
|
+
function normalizeCourseHomeCourseMetadata(metadata) {
|
|
12
|
+
const data = camelCaseObject(metadata);
|
|
13
|
+
return {
|
|
14
|
+
tabs: (data.tabs || []).map((tab) => ({
|
|
15
|
+
tabId: tab.tabId === 'courseware' ? 'outline' : tab.tabId,
|
|
16
|
+
title: tab.title,
|
|
17
|
+
url: tab.url,
|
|
18
|
+
})),
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export function getCourseHomeCourseMetadata(courseId) {
|
|
22
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
23
|
+
const { data } = yield getAuthenticatedHttpClient().get(`${getSiteConfig().lmsBaseUrl}/api/course_home/course_metadata/${courseId}`);
|
|
24
|
+
return normalizeCourseHomeCourseMetadata(data);
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../../../../shell/header/course-navigation-bar/data/service.ts"],"names":[],"mappings":";;;;;;;;;AAAA,OAAO,EAAE,aAAa,EAAE,0BAA0B,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAuBjG,SAAS,iCAAiC,CAAC,QAAqC;IAC9E,MAAM,IAAI,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;IACvC,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAc,EAAE,EAAE,CAAC,CAAC;YAC/C,KAAK,EAAE,GAAG,CAAC,KAAK,KAAK,YAAY,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK;YACzD,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,GAAG,EAAE,GAAG,CAAC,GAAG;SACb,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC;AAED,MAAM,UAAgB,2BAA2B,CAAC,QAAgB;;QAChE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,0BAA0B,EAAE,CAAC,GAAG,CAAC,GAAG,aAAa,EAAE,CAAC,UAAU,oCAAoC,QAAQ,EAAE,CAAC,CAAC;QAErI,OAAO,iCAAiC,CAAC,IAAI,CAAC,CAAC;IACjD,CAAC;CAAA","sourcesContent":["import { getSiteConfig, getAuthenticatedHttpClient, camelCaseObject } from '../../../../runtime';\n\n// Raw API response from /api/course_home/course_metadata/\ninterface RawCourseTab {\n tab_id: string,\n title: string,\n url: string,\n}\n\ninterface RawCourseHomeCourseMetadata {\n tabs: RawCourseTab[],\n}\n\nexport interface CourseTab {\n tabId: string,\n title: string,\n url: string,\n}\n\nexport interface CourseHomeCourseMetadata {\n tabs: CourseTab[],\n}\n\nfunction normalizeCourseHomeCourseMetadata(metadata: RawCourseHomeCourseMetadata): CourseHomeCourseMetadata {\n const data = camelCaseObject(metadata);\n return {\n tabs: (data.tabs || []).map((tab: CourseTab) => ({\n tabId: tab.tabId === 'courseware' ? 'outline' : tab.tabId,\n title: tab.title,\n url: tab.url,\n })),\n };\n}\n\nexport async function getCourseHomeCourseMetadata(courseId: string): Promise<CourseHomeCourseMetadata> {\n const { data } = await getAuthenticatedHttpClient().get(`${getSiteConfig().lmsBaseUrl}/api/course_home/course_metadata/${courseId}`);\n\n return normalizeCourseHomeCourseMetadata(data);\n}\n"]}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { defineMessages } from '../../../runtime';
|
|
2
|
+
const messages = defineMessages({
|
|
3
|
+
courseMaterial: {
|
|
4
|
+
id: 'org.openedx.frontend.slot.header.courseNavigationBar.tabs.label',
|
|
5
|
+
defaultMessage: 'Course Navigation Bar',
|
|
6
|
+
description: 'The accessible label for course tabs navigation',
|
|
7
|
+
},
|
|
8
|
+
});
|
|
9
|
+
export default messages;
|
|
10
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.js","sourceRoot":"","sources":["../../../../shell/header/course-navigation-bar/messages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,QAAQ,GAAG,cAAc,CAAC;IAC9B,cAAc,EAAE;QACd,EAAE,EAAE,iEAAiE;QACrE,cAAc,EAAE,uBAAuB;QACvC,WAAW,EAAE,iDAAiD;KAC/D;CACF,CAAC,CAAC;AAEH,eAAe,QAAQ,CAAC","sourcesContent":["import { defineMessages } from '../../../runtime';\n\nconst messages = defineMessages({\n courseMaterial: {\n id: 'org.openedx.frontend.slot.header.courseNavigationBar.tabs.label',\n defaultMessage: 'Course Navigation Bar',\n description: 'The accessible label for course tabs navigation',\n },\n});\n\nexport default messages;\n"]}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { matchPath } from 'react-router-dom';
|
|
2
|
+
import { getActiveRoles, getProvidedData, getUrlByRouteRole } from '../../../runtime';
|
|
3
|
+
import { courseNavigationRolesProvidesKey } from '../constants';
|
|
4
|
+
function getProviders() {
|
|
5
|
+
return getProvidedData(courseNavigationRolesProvidesKey).filter((data) => data !== null
|
|
6
|
+
&& typeof data === 'object'
|
|
7
|
+
&& 'courseNavigationRoles' in data
|
|
8
|
+
&& Array.isArray(data.courseNavigationRoles));
|
|
9
|
+
}
|
|
10
|
+
function getProvidedRoles() {
|
|
11
|
+
return getProviders().flatMap(data => data.courseNavigationRoles);
|
|
12
|
+
}
|
|
13
|
+
export function isCourseNavigationRoute() {
|
|
14
|
+
const activeRoles = getActiveRoles();
|
|
15
|
+
return getProvidedRoles().some(role => activeRoles.includes(role));
|
|
16
|
+
}
|
|
17
|
+
export function isClientRoute(pathname) {
|
|
18
|
+
return getProvidedRoles().some(role => {
|
|
19
|
+
const routePath = getUrlByRouteRole(role);
|
|
20
|
+
return routePath !== null
|
|
21
|
+
&& routePath.startsWith('/')
|
|
22
|
+
&& matchPath({ path: routePath, end: false }, pathname) !== null;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../shell/header/course-navigation-bar/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,gCAAgC,EAAE,MAAM,cAAc,CAAC;AAMhE,SAAS,YAAY;IACnB,OAAO,eAAe,CAAC,gCAAgC,CAAC,CAAC,MAAM,CAC7D,CAAC,IAAI,EAAwC,EAAE,CAC7C,IAAI,KAAK,IAAI;WACV,OAAO,IAAI,KAAK,QAAQ;WACxB,uBAAuB,IAAI,IAAI;WAC/B,KAAK,CAAC,OAAO,CAAE,IAAqC,CAAC,qBAAqB,CAAC,CACjF,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB;IACvB,OAAO,YAAY,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,uBAAuB;IACrC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IACrC,OAAO,gBAAgB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;AACrE,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAAgB;IAC5C,OAAO,gBAAgB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACpC,MAAM,SAAS,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC1C,OAAO,SAAS,KAAK,IAAI;eACpB,SAAS,CAAC,UAAU,CAAC,GAAG,CAAC;eACzB,SAAS,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,QAAQ,CAAC,KAAK,IAAI,CAAC;IACrE,CAAC,CAAC,CAAC;AACL,CAAC","sourcesContent":["import { matchPath } from 'react-router-dom';\nimport { getActiveRoles, getProvidedData, getUrlByRouteRole } from '../../../runtime';\nimport { courseNavigationRolesProvidesKey } from '../constants';\n\ninterface CourseNavigationProviderData {\n courseNavigationRoles: string[],\n}\n\nfunction getProviders(): CourseNavigationProviderData[] {\n return getProvidedData(courseNavigationRolesProvidesKey).filter(\n (data): data is CourseNavigationProviderData =>\n data !== null\n && typeof data === 'object'\n && 'courseNavigationRoles' in data\n && Array.isArray((data as CourseNavigationProviderData).courseNavigationRoles)\n );\n}\n\nfunction getProvidedRoles(): string[] {\n return getProviders().flatMap(data => data.courseNavigationRoles);\n}\n\nexport function isCourseNavigationRoute(): boolean {\n const activeRoles = getActiveRoles();\n return getProvidedRoles().some(role => activeRoles.includes(role));\n}\n\nexport function isClientRoute(pathname: string): boolean {\n return getProvidedRoles().some(role => {\n const routePath = getUrlByRouteRole(role);\n return routePath !== null\n && routePath.startsWith('/')\n && matchPath({ path: routePath, end: false }, pathname) !== null;\n });\n}\n"]}
|
package/dist/shell/site.js
CHANGED
|
@@ -14,14 +14,12 @@ import { RouterProvider } from 'react-router-dom';
|
|
|
14
14
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
15
15
|
import { SITE_INIT_ERROR, SITE_READY, initialize, subscribe } from '../runtime';
|
|
16
16
|
import { addAppConfigs } from '../runtime/config';
|
|
17
|
-
import
|
|
18
|
-
import messages from './i18n';
|
|
17
|
+
import messages from 'site.i18n';
|
|
19
18
|
import createRouter from './router/createRouter';
|
|
20
19
|
subscribe(SITE_READY, () => __awaiter(void 0, void 0, void 0, function* () {
|
|
21
20
|
const queryClient = new QueryClient();
|
|
22
21
|
const router = createRouter();
|
|
23
22
|
addAppConfigs();
|
|
24
|
-
addAppMessages();
|
|
25
23
|
const root = createRoot(document.getElementById('root'));
|
|
26
24
|
root.render(_jsx(StrictMode, { children: _jsx(QueryClientProvider, { client: queryClient, children: _jsx(RouterProvider, { router: router }) }) }));
|
|
27
25
|
}));
|
package/dist/shell/site.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../shell/site.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,UAAU,EACV,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,
|
|
1
|
+
{"version":3,"file":"site.js","sourceRoot":"","sources":["../../shell/site.tsx"],"names":[],"mappings":";;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAEzE,OAAO,EACL,eAAe,EACf,UAAU,EACV,UAAU,EACV,SAAS,EACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,QAAQ,MAAM,WAAW,CAAC;AACjC,OAAO,YAAY,MAAM,uBAAuB,CAAC;AAEjD,SAAS,CAAC,UAAU,EAAE,GAAS,EAAE;IAC/B,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC;IACtC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;IAE9B,aAAa,EAAE,CAAC;IAEhB,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAgB,CAAC,CAAC;IACxE,IAAI,CAAC,MAAM,CACT,KAAC,UAAU,cACT,KAAC,mBAAmB,IAAC,MAAM,EAAE,WAAW,YACtC,KAAC,cAAc,IAAC,MAAM,EAAE,MAAM,GAAI,GACd,GACX,CACd,CAAC;AACJ,CAAC,CAAA,CAAC,CAAC;AAEH,SAAS,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;IACnC,MAAM,IAAI,GAAG,UAAU,CAAC,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAgB,CAAC,CAAC;IACxE,IAAI,CAAC,MAAM,CAAC,wBAAM,KAAK,CAAC,OAAO,GAAO,CAAC,CAAC;AAC1C,CAAC,CAAC,CAAC;AAEH,UAAU,CAAC;IACT,QAAQ;CACT,CAAC,CAAC","sourcesContent":["import { StrictMode } from 'react';\nimport { createRoot } from 'react-dom/client';\nimport { RouterProvider } from 'react-router-dom';\nimport { QueryClient, QueryClientProvider } from '@tanstack/react-query';\n\nimport {\n SITE_INIT_ERROR,\n SITE_READY,\n initialize,\n subscribe\n} from '../runtime';\nimport { addAppConfigs } from '../runtime/config';\nimport messages from 'site.i18n';\nimport createRouter from './router/createRouter';\n\nsubscribe(SITE_READY, async () => {\n const queryClient = new QueryClient();\n const router = createRouter();\n\n addAppConfigs();\n\n const root = createRoot(document.getElementById('root') as HTMLElement);\n root.render(\n <StrictMode>\n <QueryClientProvider client={queryClient}>\n <RouterProvider router={router} />\n </QueryClientProvider>\n </StrictMode>\n );\n});\n\nsubscribe(SITE_INIT_ERROR, (error) => {\n const root = createRoot(document.getElementById('root') as HTMLElement);\n root.render(<div>{error.message}</div>);\n});\n\ninitialize({\n messages,\n});\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
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.runPrepare = runPrepare;
|
|
7
|
+
exports.runPull = runPull;
|
|
8
|
+
const child_process_1 = __importDefault(require("child_process"));
|
|
9
|
+
const translations_1 = require("../utils/translations");
|
|
10
|
+
function runPrepare() {
|
|
11
|
+
(0, translations_1.prepare)({ siteRoot: process.cwd() });
|
|
12
|
+
}
|
|
13
|
+
function runPull() {
|
|
14
|
+
(0, translations_1.pull)({
|
|
15
|
+
siteRoot: process.cwd(),
|
|
16
|
+
execFileSync: (file, args) => child_process_1.default.execFileSync(file, args, { stdio: 'inherit' }),
|
|
17
|
+
shouldPrepare: !process.argv.includes('--no-prepare'),
|
|
18
|
+
atlasOptions: process.argv.find(a => a.startsWith('--atlas-options='))?.slice('--atlas-options='.length),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
@@ -95,6 +95,12 @@ switch (commandName) {
|
|
|
95
95
|
case types_1.CommandTypes.SERVE:
|
|
96
96
|
require('./commands/serve');
|
|
97
97
|
break;
|
|
98
|
+
case types_1.CommandTypes.TRANSLATIONS_PULL:
|
|
99
|
+
require('./commands/translations').runPull();
|
|
100
|
+
break;
|
|
101
|
+
case types_1.CommandTypes.TRANSLATIONS_PREPARE:
|
|
102
|
+
require('./commands/translations').runPrepare();
|
|
103
|
+
break;
|
|
98
104
|
case types_1.CommandTypes.HELP:
|
|
99
105
|
(0, printUsage_1.default)();
|
|
100
106
|
break;
|
|
@@ -35,5 +35,13 @@ function printUsage() {
|
|
|
35
35
|
console.group();
|
|
36
36
|
console.log(`Serves the dist folder with an express server. Used to locally test production assets.\n`);
|
|
37
37
|
console.groupEnd();
|
|
38
|
+
console.log(`${chalk_1.default.bold('translations:pull')}\n`);
|
|
39
|
+
console.group();
|
|
40
|
+
console.log(`Pulls translations for all installed apps using atlas, then runs translations:prepare. Reads atlasTranslations config from package.json. Pass ${chalk_1.default.bold('--no-prepare')} to skip the prepare step.\n`);
|
|
41
|
+
console.groupEnd();
|
|
42
|
+
console.log(`${chalk_1.default.bold('translations:prepare')}\n`);
|
|
43
|
+
console.group();
|
|
44
|
+
console.log(`Generates TypeScript modules from pulled translation JSON files in src/i18n/messages/ and src/i18n/site-messages/.\n`);
|
|
45
|
+
console.groupEnd();
|
|
38
46
|
console.groupEnd();
|
|
39
47
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.pull = exports.prepare = void 0;
|
|
4
|
+
var prepare_1 = require("./prepare");
|
|
5
|
+
Object.defineProperty(exports, "prepare", { enumerable: true, get: function () { return prepare_1.prepare; } });
|
|
6
|
+
var pull_1 = require("./pull");
|
|
7
|
+
Object.defineProperty(exports, "pull", { enumerable: true, get: function () { return pull_1.pull; } });
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface LocaleImport {
|
|
2
|
+
localeName: string;
|
|
3
|
+
filename: string;
|
|
4
|
+
}
|
|
5
|
+
export interface LocaleEntry {
|
|
6
|
+
key: string;
|
|
7
|
+
varName: string;
|
|
8
|
+
}
|
|
9
|
+
export interface MessagesObject {
|
|
10
|
+
imports: LocaleImport[];
|
|
11
|
+
entries: LocaleEntry[];
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reads all locale JSON files in a directory and returns the data needed to
|
|
15
|
+
* render a messages object ({ 'ar': ar, 'es-419': es_419 }).
|
|
16
|
+
* Returns null if no non-empty JSON files are found.
|
|
17
|
+
*/
|
|
18
|
+
export declare function generateMessagesObject(dirPath: string): MessagesObject | null;
|
|
19
|
+
export declare function renderImportLine({ localeName, filename }: LocaleImport): string;
|
|
20
|
+
export declare function renderImportsBlock(messagesObject: MessagesObject): string;
|
|
21
|
+
export declare function renderExportLine({ key, varName }: LocaleEntry): string;
|
|
22
|
+
export declare function renderExportBlock(messagesObject: MessagesObject): string;
|
|
23
|
+
/**
|
|
24
|
+
* Renders a MessagesObject and writes it to an index.ts file in the given directory.
|
|
25
|
+
*/
|
|
26
|
+
export declare function writeMessagesObjectToFile(dirPath: string, messagesObject: MessagesObject): void;
|
|
@@ -0,0 +1,66 @@
|
|
|
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.generateMessagesObject = generateMessagesObject;
|
|
7
|
+
exports.renderImportLine = renderImportLine;
|
|
8
|
+
exports.renderImportsBlock = renderImportsBlock;
|
|
9
|
+
exports.renderExportLine = renderExportLine;
|
|
10
|
+
exports.renderExportBlock = renderExportBlock;
|
|
11
|
+
exports.writeMessagesObjectToFile = writeMessagesObjectToFile;
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
/**
|
|
15
|
+
* Reads all locale JSON files in a directory and returns the data needed to
|
|
16
|
+
* render a messages object ({ 'ar': ar, 'es-419': es_419 }).
|
|
17
|
+
* Returns null if no non-empty JSON files are found.
|
|
18
|
+
*/
|
|
19
|
+
function generateMessagesObject(dirPath) {
|
|
20
|
+
const dirEntries = fs_1.default.readdirSync(dirPath, { withFileTypes: true });
|
|
21
|
+
const jsonFiles = dirEntries
|
|
22
|
+
.filter(e => e.isFile() && e.name.endsWith('.json'))
|
|
23
|
+
.map(e => e.name);
|
|
24
|
+
const imports = [];
|
|
25
|
+
const entries = [];
|
|
26
|
+
for (const filename of jsonFiles) {
|
|
27
|
+
const localeName = filename.replace(/\.json$/, '');
|
|
28
|
+
const key = localeName.toLowerCase().replace(/_/g, '-');
|
|
29
|
+
const filePath = path_1.default.join(dirPath, filename);
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(fs_1.default.readFileSync(filePath, { encoding: 'utf8' }));
|
|
32
|
+
if (!Object.keys(parsed).length) {
|
|
33
|
+
continue; // skip empty files
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
imports.push({ localeName, filename });
|
|
40
|
+
entries.push({ key, varName: localeName });
|
|
41
|
+
}
|
|
42
|
+
if (!imports.length) {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
return { imports, entries };
|
|
46
|
+
}
|
|
47
|
+
function renderImportLine({ localeName, filename }) {
|
|
48
|
+
return `import ${localeName} from './${filename}';`;
|
|
49
|
+
}
|
|
50
|
+
function renderImportsBlock(messagesObject) {
|
|
51
|
+
return messagesObject.imports.map(renderImportLine).join('\n');
|
|
52
|
+
}
|
|
53
|
+
function renderExportLine({ key, varName }) {
|
|
54
|
+
return ` '${key}': ${varName},`;
|
|
55
|
+
}
|
|
56
|
+
function renderExportBlock(messagesObject) {
|
|
57
|
+
const lines = messagesObject.entries.map(renderExportLine).join('\n');
|
|
58
|
+
return `export default {\n${lines}\n};\n`;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Renders a MessagesObject and writes it to an index.ts file in the given directory.
|
|
62
|
+
*/
|
|
63
|
+
function writeMessagesObjectToFile(dirPath, messagesObject) {
|
|
64
|
+
const content = `${renderImportsBlock(messagesObject)}\n\n${renderExportBlock(messagesObject)}`;
|
|
65
|
+
fs_1.default.writeFileSync(path_1.default.join(dirPath, 'index.ts'), content);
|
|
66
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
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.prepareAllPackageMessages = prepareAllPackageMessages;
|
|
7
|
+
exports.prepareSiteMessages = prepareSiteMessages;
|
|
8
|
+
exports.prepare = prepare;
|
|
9
|
+
const fs_1 = __importDefault(require("fs"));
|
|
10
|
+
const lodash_camelcase_1 = __importDefault(require("lodash.camelcase"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const messagesObject_1 = require("./messagesObject");
|
|
13
|
+
function packageVarName(packagePath) {
|
|
14
|
+
const name = packagePath.split('/').pop();
|
|
15
|
+
return `${(0, lodash_camelcase_1.default)(name)}Messages`;
|
|
16
|
+
}
|
|
17
|
+
function getPackageMessages(messagesDir, packagePath) {
|
|
18
|
+
return (0, messagesObject_1.generateMessagesObject)(path_1.default.join(messagesDir, packagePath));
|
|
19
|
+
}
|
|
20
|
+
function getPackagePaths(messagesDir) {
|
|
21
|
+
const directoryEntries = fs_1.default.readdirSync(messagesDir, { withFileTypes: true })
|
|
22
|
+
.filter(e => e.isDirectory());
|
|
23
|
+
const packagePaths = [];
|
|
24
|
+
for (const entry of directoryEntries) {
|
|
25
|
+
const directory = fs_1.default.readdirSync(path_1.default.join(messagesDir, entry.name), { withFileTypes: true });
|
|
26
|
+
if (!directory.some(e => e.isDirectory())) {
|
|
27
|
+
// no subdirectories, this is a package dir
|
|
28
|
+
packagePaths.push(entry.name);
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// this is a scope dir, subdirs are packages
|
|
32
|
+
const packageDirs = directory.filter(e => e.isDirectory());
|
|
33
|
+
for (const pkg of packageDirs) {
|
|
34
|
+
packagePaths.push(`${entry.name}/${pkg.name}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
return packagePaths;
|
|
38
|
+
}
|
|
39
|
+
function getAllPackageMessages(messagesDir) {
|
|
40
|
+
if (!fs_1.default.existsSync(messagesDir)) {
|
|
41
|
+
// directory doesn't exist
|
|
42
|
+
return new Map();
|
|
43
|
+
}
|
|
44
|
+
const directory = fs_1.default.readdirSync(messagesDir, { withFileTypes: true });
|
|
45
|
+
if (!directory.some(e => e.isDirectory())) {
|
|
46
|
+
// directory exists but has no subdirectories
|
|
47
|
+
return new Map();
|
|
48
|
+
}
|
|
49
|
+
const packagePaths = getPackagePaths(messagesDir);
|
|
50
|
+
const result = new Map();
|
|
51
|
+
for (const packagePath of packagePaths) {
|
|
52
|
+
const messagesObject = getPackageMessages(messagesDir, packagePath);
|
|
53
|
+
if (messagesObject) {
|
|
54
|
+
result.set(packagePath, messagesObject);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
function prepareAllPackageMessages(messagesDir) {
|
|
60
|
+
const packageMessages = getAllPackageMessages(messagesDir);
|
|
61
|
+
const importLines = [];
|
|
62
|
+
const exportItems = [];
|
|
63
|
+
for (const [packagePath, messagesObject] of packageMessages) {
|
|
64
|
+
(0, messagesObject_1.writeMessagesObjectToFile)(path_1.default.join(messagesDir, packagePath), messagesObject);
|
|
65
|
+
const varName = packageVarName(packagePath);
|
|
66
|
+
importLines.push(`import ${varName} from './messages/${packagePath}';`);
|
|
67
|
+
exportItems.push(` ${varName},`);
|
|
68
|
+
}
|
|
69
|
+
return [importLines, exportItems];
|
|
70
|
+
}
|
|
71
|
+
function prepareSiteMessages(siteMessagesDir) {
|
|
72
|
+
const siteMessages = fs_1.default.existsSync(siteMessagesDir)
|
|
73
|
+
? (0, messagesObject_1.generateMessagesObject)(siteMessagesDir)
|
|
74
|
+
: null;
|
|
75
|
+
if (!siteMessages) {
|
|
76
|
+
return [[], []];
|
|
77
|
+
}
|
|
78
|
+
(0, messagesObject_1.writeMessagesObjectToFile)(siteMessagesDir, siteMessages);
|
|
79
|
+
return [
|
|
80
|
+
[`import siteMessages from './site-messages';`],
|
|
81
|
+
[` siteMessages,`],
|
|
82
|
+
];
|
|
83
|
+
}
|
|
84
|
+
function prepare({ siteRoot }) {
|
|
85
|
+
const i18nDir = path_1.default.join(siteRoot, 'src', 'i18n');
|
|
86
|
+
const messagesDir = path_1.default.join(i18nDir, 'messages');
|
|
87
|
+
const siteMessagesDir = path_1.default.join(i18nDir, 'site-messages');
|
|
88
|
+
const [packageImportLines, packageExportItems] = prepareAllPackageMessages(messagesDir);
|
|
89
|
+
const [siteImportLines, siteExportItems] = prepareSiteMessages(siteMessagesDir);
|
|
90
|
+
const importLines = [...packageImportLines, ...siteImportLines];
|
|
91
|
+
const exportItems = [...packageExportItems, ...siteExportItems];
|
|
92
|
+
const hasMessages = importLines.length > 0 && exportItems.length > 0;
|
|
93
|
+
const messagesContent = hasMessages
|
|
94
|
+
? `${importLines.join('\n')}\n\nexport default [\n${exportItems.join('\n')}\n];\n`
|
|
95
|
+
: 'export default [];\n';
|
|
96
|
+
fs_1.default.mkdirSync(i18nDir, { recursive: true });
|
|
97
|
+
fs_1.default.writeFileSync(path_1.default.join(i18nDir, 'messages.ts'), messagesContent);
|
|
98
|
+
}
|
|
@@ -0,0 +1,102 @@
|
|
|
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.pull = pull;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const prepare_1 = require("./prepare");
|
|
10
|
+
function validateSiteTranslationsConfig(siteRoot) {
|
|
11
|
+
const pkgJsonPath = path_1.default.join(siteRoot, 'package.json');
|
|
12
|
+
let config;
|
|
13
|
+
try {
|
|
14
|
+
config = JSON.parse(fs_1.default.readFileSync(pkgJsonPath, { encoding: 'utf8' }));
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
throw new Error(`translations:pull: Could not read ${pkgJsonPath}`);
|
|
18
|
+
}
|
|
19
|
+
if (!config.atlasTranslations) {
|
|
20
|
+
throw new Error(`translations:pull: No atlasTranslations field in ${pkgJsonPath}. `
|
|
21
|
+
+ 'Add an atlasTranslations config to enable translation pulling.');
|
|
22
|
+
}
|
|
23
|
+
if (config.atlasTranslations.path && !config.name) {
|
|
24
|
+
throw new Error(`translations:pull: atlasTranslations.path is set in ${pkgJsonPath} but there is no name field. `
|
|
25
|
+
+ 'A name field is required to identify this package as a translation source.');
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
function readTranslationsConfig(pkgJsonPath, nodeModulesBase) {
|
|
29
|
+
const packageName = path_1.default.relative(nodeModulesBase, path_1.default.dirname(pkgJsonPath));
|
|
30
|
+
if (!fs_1.default.existsSync(pkgJsonPath)) {
|
|
31
|
+
console.warn(`translations:pull: Package ${packageName} not found in node_modules, skipping.`);
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
let config;
|
|
35
|
+
try {
|
|
36
|
+
config = JSON.parse(fs_1.default.readFileSync(pkgJsonPath, { encoding: 'utf8' }));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
console.warn(`translations:pull: Error reading package.json for ${packageName}, skipping.`);
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
const resolvedPackageName = config.name ?? packageName;
|
|
43
|
+
if (!config.atlasTranslations) {
|
|
44
|
+
console.warn(`translations:pull: No atlasTranslations config in ${resolvedPackageName}, skipping.`);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
return { packageName: resolvedPackageName, config };
|
|
48
|
+
}
|
|
49
|
+
function resolveTranslationMappings(pkgJsonPath, nodeModulesBase) {
|
|
50
|
+
const visited = new Set();
|
|
51
|
+
function resolve(pkgJsonPath, ancestors) {
|
|
52
|
+
const read = readTranslationsConfig(pkgJsonPath, nodeModulesBase);
|
|
53
|
+
if (!read)
|
|
54
|
+
return [];
|
|
55
|
+
const { packageName, config } = read;
|
|
56
|
+
if (ancestors.includes(packageName)) {
|
|
57
|
+
console.warn(`translations:pull: Circular dependency detected: ${[...ancestors, packageName].join(' → ')}, skipping.`);
|
|
58
|
+
return [];
|
|
59
|
+
}
|
|
60
|
+
if (visited.has(packageName)) {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
visited.add(packageName);
|
|
64
|
+
const results = [];
|
|
65
|
+
const mapping = config.atlasTranslations?.path
|
|
66
|
+
? { from: config.atlasTranslations.path, to: packageName }
|
|
67
|
+
: null;
|
|
68
|
+
if (mapping) {
|
|
69
|
+
results.push(mapping);
|
|
70
|
+
}
|
|
71
|
+
const dependencies = config.atlasTranslations?.dependencies ?? [];
|
|
72
|
+
for (const dep of dependencies) {
|
|
73
|
+
results.push(...resolve(path_1.default.join(nodeModulesBase, dep, 'package.json'), [...ancestors, packageName]));
|
|
74
|
+
}
|
|
75
|
+
return results;
|
|
76
|
+
}
|
|
77
|
+
return resolve(pkgJsonPath, []);
|
|
78
|
+
}
|
|
79
|
+
function clearMessages(messagesDir) {
|
|
80
|
+
if (fs_1.default.existsSync(messagesDir)) {
|
|
81
|
+
fs_1.default.rmSync(messagesDir, { recursive: true });
|
|
82
|
+
}
|
|
83
|
+
fs_1.default.mkdirSync(messagesDir, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
function pull({ siteRoot, execFileSync, shouldPrepare, atlasOptions = '', }) {
|
|
86
|
+
validateSiteTranslationsConfig(siteRoot);
|
|
87
|
+
// only interact with messages dir, not site-messages
|
|
88
|
+
const messagesDir = path_1.default.join(siteRoot, 'src', 'i18n', 'messages');
|
|
89
|
+
const nodeModulesBase = path_1.default.join(siteRoot, 'node_modules');
|
|
90
|
+
clearMessages(messagesDir);
|
|
91
|
+
const mappings = resolveTranslationMappings(path_1.default.join(siteRoot, 'package.json'), nodeModulesBase);
|
|
92
|
+
if (!mappings.length) {
|
|
93
|
+
if (shouldPrepare)
|
|
94
|
+
(0, prepare_1.prepare)({ siteRoot });
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const atlasOptionsArgs = atlasOptions.trim().split(/\s+/).filter(Boolean);
|
|
98
|
+
const atlasMappingArgs = mappings.map(m => `${m.from}:src/i18n/messages/${m.to}`);
|
|
99
|
+
execFileSync('atlas', ['pull', ...atlasOptionsArgs, ...atlasMappingArgs]);
|
|
100
|
+
if (shouldPrepare)
|
|
101
|
+
(0, prepare_1.prepare)({ siteRoot });
|
|
102
|
+
}
|
package/dist/tools/types.d.ts
CHANGED
package/dist/tools/types.js
CHANGED
|
@@ -19,5 +19,7 @@ var CommandTypes;
|
|
|
19
19
|
CommandTypes["DEV"] = "dev";
|
|
20
20
|
CommandTypes["FORMAT_JS"] = "formatjs";
|
|
21
21
|
CommandTypes["SERVE"] = "serve";
|
|
22
|
+
CommandTypes["TRANSLATIONS_PULL"] = "translations:pull";
|
|
23
|
+
CommandTypes["TRANSLATIONS_PREPARE"] = "translations:prepare";
|
|
22
24
|
CommandTypes["HELP"] = "help";
|
|
23
25
|
})(CommandTypes || (exports.CommandTypes = CommandTypes = {}));
|
|
@@ -4,3 +4,4 @@ export { default as getImageMinimizer } from './all/getImageMinimizer';
|
|
|
4
4
|
export { default as getStylesheetRule } from './all/getStylesheetRule';
|
|
5
5
|
export { default as getDevServer } from './dev/getDevServer';
|
|
6
6
|
export { default as getHtmlWebpackPlugin } from './site/getHtmlWebpackPlugin';
|
|
7
|
+
export { default as getI18nMessagesFallbackPlugin } from './site/getI18nMessagesFallbackPlugin';
|
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.getHtmlWebpackPlugin = exports.getDevServer = exports.getStylesheetRule = exports.getImageMinimizer = exports.getFileLoaderRules = exports.getCodeRules = void 0;
|
|
6
|
+
exports.getI18nMessagesFallbackPlugin = exports.getHtmlWebpackPlugin = exports.getDevServer = exports.getStylesheetRule = exports.getImageMinimizer = exports.getFileLoaderRules = exports.getCodeRules = void 0;
|
|
7
7
|
var getCodeRules_1 = require("./all/getCodeRules");
|
|
8
8
|
Object.defineProperty(exports, "getCodeRules", { enumerable: true, get: function () { return __importDefault(getCodeRules_1).default; } });
|
|
9
9
|
var getFileLoaderRules_1 = require("./all/getFileLoaderRules");
|
|
@@ -16,3 +16,5 @@ var getDevServer_1 = require("./dev/getDevServer");
|
|
|
16
16
|
Object.defineProperty(exports, "getDevServer", { enumerable: true, get: function () { return __importDefault(getDevServer_1).default; } });
|
|
17
17
|
var getHtmlWebpackPlugin_1 = require("./site/getHtmlWebpackPlugin");
|
|
18
18
|
Object.defineProperty(exports, "getHtmlWebpackPlugin", { enumerable: true, get: function () { return __importDefault(getHtmlWebpackPlugin_1).default; } });
|
|
19
|
+
var getI18nMessagesFallbackPlugin_1 = require("./site/getI18nMessagesFallbackPlugin");
|
|
20
|
+
Object.defineProperty(exports, "getI18nMessagesFallbackPlugin", { enumerable: true, get: function () { return __importDefault(getI18nMessagesFallbackPlugin_1).default; } });
|
|
@@ -0,0 +1,26 @@
|
|
|
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 = getI18nMessagesFallbackPlugin;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const webpack_1 = __importDefault(require("webpack"));
|
|
10
|
+
// When messages.ts hasn't been generated yet (i.e. translations:pull hasn't been run),
|
|
11
|
+
// replace the ./messages import in src/i18n/index.ts with an empty fallback so webpack
|
|
12
|
+
// doesn't error on the missing file.
|
|
13
|
+
function getI18nMessagesFallbackPlugin() {
|
|
14
|
+
return new webpack_1.default.NormalModuleReplacementPlugin(
|
|
15
|
+
// Matches the raw import string `./messages` — anchored to avoid partial matches.
|
|
16
|
+
/^\.\/messages$/, (resource) => {
|
|
17
|
+
// Only apply to imports from src/i18n/ — exact match to avoid false positives.
|
|
18
|
+
if (resource.context !== path_1.default.resolve(process.cwd(), 'src', 'i18n'))
|
|
19
|
+
return;
|
|
20
|
+
// If messages.ts exists, let webpack resolve it normally.
|
|
21
|
+
if (fs_1.default.existsSync(path_1.default.join(resource.context, 'messages.ts')))
|
|
22
|
+
return;
|
|
23
|
+
// File is missing — substitute the empty fallback module.
|
|
24
|
+
resource.request = require.resolve('./emptyI18n');
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function getResolvedSiteI18nPath(defaultDirname: string): string;
|
|
@@ -0,0 +1,25 @@
|
|
|
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 = getResolvedSiteI18nPath;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
function getResolvedSiteI18nPath(defaultDirname) {
|
|
10
|
+
const siteI18nPath = process.env.SITE_I18N_PATH;
|
|
11
|
+
if (siteI18nPath !== undefined) {
|
|
12
|
+
const absolutePath = path_1.default.resolve(process.cwd(), siteI18nPath);
|
|
13
|
+
if (fs_1.default.existsSync(absolutePath)) {
|
|
14
|
+
return absolutePath;
|
|
15
|
+
}
|
|
16
|
+
console.error(`Invalid site i18n path (${siteI18nPath}) specified as an environment variable. Aborting.`);
|
|
17
|
+
process.exit(1);
|
|
18
|
+
}
|
|
19
|
+
const defaultPath = path_1.default.resolve(process.cwd(), defaultDirname);
|
|
20
|
+
if (fs_1.default.existsSync(defaultPath)) {
|
|
21
|
+
return defaultPath;
|
|
22
|
+
}
|
|
23
|
+
console.error(`Default site i18n directory (${defaultPath}) does not exist. Aborting.`);
|
|
24
|
+
process.exit(1);
|
|
25
|
+
}
|