@openedx/frontend-base 1.0.0-alpha.40 → 1.0.0-alpha.41
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.js +29 -18
- package/dist/runtime/config/index.js.map +1 -1
- package/dist/runtime/i18n/lib.js +1 -1
- package/dist/runtime/i18n/lib.js.map +1 -1
- package/dist/runtime/react/CombinedAppProvider.d.ts +1 -1
- package/dist/runtime/react/CombinedAppProvider.js +14 -18
- package/dist/runtime/react/CombinedAppProvider.js.map +1 -1
- package/dist/runtime/react/hooks/useActiveRoles.js +6 -3
- package/dist/runtime/react/hooks/useActiveRoles.js.map +1 -1
- package/dist/runtime/react/hooks/useActiveRouteRoleWatcher.js +3 -9
- package/dist/runtime/react/hooks/useActiveRouteRoleWatcher.js.map +1 -1
- package/dist/runtime/slots/Slot.d.ts +3 -2
- package/dist/runtime/slots/Slot.js +4 -2
- package/dist/runtime/slots/Slot.js.map +1 -1
- package/dist/runtime/slots/hooks.d.ts +3 -5
- package/dist/runtime/slots/hooks.js +6 -16
- package/dist/runtime/slots/hooks.js.map +1 -1
- package/dist/runtime/slots/layout/hooks.d.ts +1 -2
- package/dist/runtime/slots/layout/hooks.js +19 -24
- package/dist/runtime/slots/layout/hooks.js.map +1 -1
- package/dist/runtime/slots/utils.d.ts +1 -1
- package/dist/runtime/slots/utils.js +2 -3
- package/dist/runtime/slots/utils.js.map +1 -1
- package/dist/runtime/slots/widget/hooks.d.ts +1 -2
- package/dist/runtime/slots/widget/hooks.js +36 -56
- package/dist/runtime/slots/widget/hooks.js.map +1 -1
- package/dist/runtime/slots/widget/utils.js +17 -20
- package/dist/runtime/slots/widget/utils.js.map +1 -1
- package/dist/runtime/utils.js +2 -2
- package/dist/runtime/utils.js.map +1 -1
- package/dist/tools/cli/utils/translations/prepare.js +2 -2
- package/package.json +3 -9
|
@@ -110,8 +110,9 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
110
110
|
}
|
|
111
111
|
return t;
|
|
112
112
|
};
|
|
113
|
-
import
|
|
114
|
-
import
|
|
113
|
+
import isEqual from 'lodash/isEqual';
|
|
114
|
+
import keyBy from 'lodash/keyBy';
|
|
115
|
+
import merge from 'lodash/merge';
|
|
115
116
|
import { EnvironmentTypes } from '../../types';
|
|
116
117
|
import { ACTIVE_ROLES_CHANGED, CONFIG_CHANGED } from '../constants';
|
|
117
118
|
import { publish } from '../subscriptions';
|
|
@@ -206,8 +207,10 @@ export function mergeSiteConfig(newSiteConfig, options = {}) {
|
|
|
206
207
|
var _a;
|
|
207
208
|
const { limitAppMergeToConfig = false } = options;
|
|
208
209
|
const { apps: newApps } = newSiteConfig, restOfNewConfig = __rest(newSiteConfig, ["apps"]);
|
|
209
|
-
|
|
210
|
-
|
|
210
|
+
/* `merge({}, ...)` deep-clones into the fresh target, so the new `siteConfig`
|
|
211
|
+
is a brand-new reference and the previous one is never mutated. This is what
|
|
212
|
+
lets React consumers detect that CONFIG_CHANGED actually changed something. */
|
|
213
|
+
siteConfig = merge({}, siteConfig, restOfNewConfig);
|
|
211
214
|
// if we don't have new apps, we're done
|
|
212
215
|
if (!(newApps === null || newApps === void 0 ? void 0 : newApps.length)) {
|
|
213
216
|
publish(CONFIG_CHANGED);
|
|
@@ -215,7 +218,7 @@ export function mergeSiteConfig(newSiteConfig, options = {}) {
|
|
|
215
218
|
}
|
|
216
219
|
// if we're doing a full merge, merge the objects
|
|
217
220
|
if (!limitAppMergeToConfig) {
|
|
218
|
-
siteConfig.apps = Object.values(merge(keyBy(siteConfig.apps || [], 'appId'), keyBy(newApps, 'appId')));
|
|
221
|
+
siteConfig.apps = Object.values(merge({}, keyBy(siteConfig.apps || [], 'appId'), keyBy(newApps, 'appId')));
|
|
219
222
|
publish(CONFIG_CHANGED);
|
|
220
223
|
return;
|
|
221
224
|
}
|
|
@@ -227,12 +230,13 @@ export function mergeSiteConfig(newSiteConfig, options = {}) {
|
|
|
227
230
|
}
|
|
228
231
|
// handle config-only merging
|
|
229
232
|
const newAppsById = keyBy(newApps, 'appId');
|
|
230
|
-
|
|
233
|
+
siteConfig.apps = siteConfig.apps.map((app) => {
|
|
231
234
|
const newApp = newAppsById[app.appId];
|
|
232
|
-
if (newApp === null || newApp === void 0 ? void 0 : newApp.config) {
|
|
233
|
-
|
|
235
|
+
if (!(newApp === null || newApp === void 0 ? void 0 : newApp.config)) {
|
|
236
|
+
return app;
|
|
234
237
|
}
|
|
235
|
-
|
|
238
|
+
return Object.assign(Object.assign({}, app), { config: merge({}, app.config, newApp.config) });
|
|
239
|
+
});
|
|
236
240
|
publish(CONFIG_CHANGED);
|
|
237
241
|
}
|
|
238
242
|
const appConfigs = {};
|
|
@@ -261,11 +265,15 @@ export function getAppConfig(id) {
|
|
|
261
265
|
return merge({}, commonAppConfig, appConfigs[id]);
|
|
262
266
|
}
|
|
263
267
|
export function mergeAppConfig(id, newAppConfig) {
|
|
264
|
-
|
|
268
|
+
// Non-mutating: produce a fresh entry so consumers holding a reference to
|
|
269
|
+
// the previous one don't observe the change underneath them.
|
|
270
|
+
appConfigs[id] = merge({}, appConfigs[id], newAppConfig);
|
|
265
271
|
publish(CONFIG_CHANGED);
|
|
266
272
|
}
|
|
267
273
|
let activeRouteRoles = [];
|
|
268
274
|
export function setActiveRouteRoles(roles) {
|
|
275
|
+
if (isEqual(activeRouteRoles, roles))
|
|
276
|
+
return;
|
|
269
277
|
activeRouteRoles = roles;
|
|
270
278
|
publish(ACTIVE_ROLES_CHANGED);
|
|
271
279
|
}
|
|
@@ -274,19 +282,22 @@ export function getActiveRouteRoles() {
|
|
|
274
282
|
}
|
|
275
283
|
const activeWidgetRoles = {};
|
|
276
284
|
export function addActiveWidgetRole(role) {
|
|
277
|
-
var _a;
|
|
278
|
-
|
|
279
|
-
activeWidgetRoles[role]
|
|
280
|
-
|
|
285
|
+
var _a, _b;
|
|
286
|
+
// Only publish when the role transitions from absent to present.
|
|
287
|
+
const wasPresent = ((_a = activeWidgetRoles[role]) !== null && _a !== void 0 ? _a : 0) > 0;
|
|
288
|
+
activeWidgetRoles[role] = ((_b = activeWidgetRoles[role]) !== null && _b !== void 0 ? _b : 0) + 1;
|
|
289
|
+
if (!wasPresent)
|
|
290
|
+
publish(ACTIVE_ROLES_CHANGED);
|
|
281
291
|
}
|
|
282
292
|
export function removeActiveWidgetRole(role) {
|
|
283
|
-
if (activeWidgetRoles[role]
|
|
284
|
-
|
|
285
|
-
|
|
293
|
+
if (activeWidgetRoles[role] === undefined)
|
|
294
|
+
return;
|
|
295
|
+
activeWidgetRoles[role] -= 1;
|
|
286
296
|
if (activeWidgetRoles[role] < 1) {
|
|
287
297
|
delete activeWidgetRoles[role];
|
|
298
|
+
// Only publish when the role transitions from present to absent.
|
|
299
|
+
publish(ACTIVE_ROLES_CHANGED);
|
|
288
300
|
}
|
|
289
|
-
publish(ACTIVE_ROLES_CHANGED);
|
|
290
301
|
}
|
|
291
302
|
export function getActiveWidgetRoles() {
|
|
292
303
|
return Object.entries(activeWidgetRoles)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../runtime/config/index.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * #### Import members from **@edx/frontend-base**\n *\n * The configuration module provides utilities for working with an application's configuration\n * document (SiteConfig). Configuration variables can be supplied to the\n * application in three different ways. They are applied in the following order:\n *\n * - Site Configuration File (site.config.tsx)\n * - Initialization Config Handler\n * - Runtime Configuration\n *\n * Last one in wins, and are deep merged together. Variables with the same name defined via the\n * later methods will override any defined using an earlier method. i.e., if a variable is defined\n * in Runtime Configuration, that will override the same variable defined in either of the earlier\n * methods. Configuration defined in a JS file will override any default values below.\n *\n * ##### Site Configuration File\n *\n * Configuration variables can be supplied in a file named site.config.tsx. This file must\n * export either an Object containing configuration variables or a function. The function must\n * return an Object containing configuration variables or, alternately, a promise which resolves to\n * an Object.\n *\n * Using a function or async function allows the configuration to be resolved at runtime (because\n * the function will be executed at runtime). This is not common, and the capability is included\n * for the sake of flexibility.\n *\n * The Site Configuration File is well-suited to extensibility use cases or component overrides,\n * in that the configuration file can depend on any installed JavaScript module. It is also the\n * preferred way of doing build-time configuration if runtime configuration isn't used by your\n * deployment of the platform.\n *\n * Exporting a config object:\n * ```\n * const siteConfig = {\n * lmsBaseUrl: 'http://localhost:18000'\n * };\n *\n * export default siteConfig;\n * ```\n *\n * Exporting a function that returns an object:\n * ```\n * function getSiteConfig() {\n * return {\n * lmsBaseUrl: 'http://localhost:18000'\n * };\n * }\n * ```\n *\n * Exporting a function that returns a promise that resolves to an object:\n * ```\n * function getAsyncSiteConfig() {\n * return new Promise((resolve, reject) => {\n * resolve({\n * lmsBaseUrl: 'http://localhost:18000'\n * });\n * });\n * }\n *\n * export default getAsyncSiteConfig;\n * ```\n *\n * ##### Initialization Config Handler\n *\n * The configuration document can be extended by\n * applications at run-time using a `config` initialization handler. Please see the Initialization\n * documentation for more information on handlers and initialization phases.\n *\n * ```\n * initialize({\n * handlers: {\n * config: () => {\n * mergeSiteConfig({\n * CUSTOM_VARIABLE: 'custom value',\n * lmsBaseUrl: 'http://localhost:18001' // You can override variables, but this is uncommon.\n * }, 'App config override handler');\n * },\n * },\n * });\n * ```\n *\n * ##### Runtime Configuration\n *\n * Configuration variables can also be supplied using the \"runtime configuration\" method, taking\n * advantage of the Micro-frontend Config API in edx-platform. More information on this API can be\n * found in the ADR which introduced it:\n *\n * https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst\n *\n * The runtime configuration method can be enabled by supplying a runtimeConfigJsonUrl via one of the other\n * two configuration methods above.\n *\n * Runtime configuration is particularly useful if you need to supply different configurations to\n * a single deployment of a micro-frontend, for instance. It is also a perfectly valid alternative\n * to build-time configuration, though it introduces an additional API call to edx-platform on MFE\n * initialization.\n *\n *\n * @module Config\n */\n\nimport keyBy from 'lodash.keyby';\nimport merge from 'lodash.merge';\nimport {\n AppConfig,\n EnvironmentTypes,\n SiteConfig\n} from '../../types';\nimport { ACTIVE_ROLES_CHANGED, CONFIG_CHANGED } from '../constants';\nimport { publish } from '../subscriptions';\n\nlet siteConfig: SiteConfig = {\n // Required\n siteId: '',\n baseUrl: '',\n siteName: '',\n loginUrl: '',\n logoutUrl: '',\n lmsBaseUrl: '',\n\n // Optional\n environment: EnvironmentTypes.PRODUCTION,\n apps: [],\n externalRoutes: [],\n externalLinkUrlOverrides: [],\n runtimeConfigJsonUrl: null,\n theme: {},\n accessTokenCookieName: 'edx-jwt-cookie-header-payload',\n csrfTokenApiPath: '/csrf/api/v1/token',\n ignoredErrorRegex: null,\n languagePreferenceCookieName: 'openedx-language-preference',\n refreshAccessTokenApiPath: '/login_refresh',\n userInfoCookieName: 'edx-user-info',\n segmentKey: null,\n};\n\n/**\n * Getter for the application configuration document. This is synchronous and merely returns a\n * reference to an existing object, and is thus safe to call as often as desired.\n *\n * Example:\n *\n * ```\n * import { getSiteConfig } from '@openedx/frontend-base';\n *\n * const {\n * lmsBaseUrl,\n * } = getSiteConfig();\n * ```\n *\n * @returns {SiteConfig}\n */\nexport function getSiteConfig() {\n return siteConfig;\n}\n\n/**\n * Replaces the existing SiteConfig. This is not commonly used, but can be helpful for tests.\n *\n * Example:\n *\n * ```\n * import { setSiteConfig } from '@openedx/frontend-base';\n *\n * setSiteConfig({\n * lmsBaseUrl, // This is overriding the ENTIRE document - this is not merged in!\n * });\n * ```\n *\n * @param newConfig A replacement SiteConfig which will completely override the current SiteConfig.\n */\nexport function setSiteConfig(newSiteConfig: SiteConfig) {\n siteConfig = newSiteConfig;\n publish(CONFIG_CHANGED);\n}\n\ninterface MergeSiteConfigOptions {\n limitAppMergeToConfig?: boolean,\n}\n\n/**\n * Merges additional configuration values into the site config returned by `getSiteConfig`. Will\n * override any values that exist with the same keys.\n *\n * ```\n * mergeSiteConfig({\n * NEW_KEY: 'new value',\n * OTHER_NEW_KEY: 'other new value',\n * });\n *\n * This function uses lodash.merge internally to merge configuration objects\n * which means they will be merged recursively. See https://lodash.com/docs/latest#merge for\n * documentation on the exact behavior.\n *\n * Apps are merged by appId rather than array index. By default, apps in the incoming config\n * that don't exist in the current config will be added.\n *\n * When `limitAppMergeToConfig` is true:\n * - All non-app parts of the config are still merged normally\n * - Only the `config` property of each existing app is merged\n * - Apps in the incoming config that don't exist in the current config are ignored\n *\n * @param {Object} newSiteConfig\n * @param {Object} options\n * @param {boolean} options.limitAppMergeToConfig - Limit app merging to only the config property of existing apps\n */\nexport function mergeSiteConfig(\n newSiteConfig: Partial<SiteConfig>,\n options: MergeSiteConfigOptions = {}\n) {\n const { limitAppMergeToConfig = false } = options;\n const { apps: newApps, ...restOfNewConfig } = newSiteConfig;\n\n // lodash merge the top-level (non-app) part\n siteConfig = merge(siteConfig, restOfNewConfig);\n\n // if we don't have new apps, we're done\n if (!newApps?.length) {\n publish(CONFIG_CHANGED);\n return;\n }\n\n // if we're doing a full merge, merge the objects\n if (!limitAppMergeToConfig) {\n siteConfig.apps = Object.values(merge(\n keyBy(siteConfig.apps || [], 'appId'),\n keyBy(newApps, 'appId')\n ));\n publish(CONFIG_CHANGED);\n return;\n }\n\n // we're doing a config-only merge, if we don't\n // have apps already, we can't update their configs\n if (!siteConfig.apps?.length) {\n publish(CONFIG_CHANGED);\n return;\n }\n\n // handle config-only merging\n const newAppsById = keyBy(newApps, 'appId');\n for (const app of siteConfig.apps) {\n const newApp = newAppsById[app.appId];\n if (newApp?.config) {\n app.config = merge(app.config, newApp.config);\n }\n }\n\n publish(CONFIG_CHANGED);\n}\n\nconst appConfigs: Record<string, AppConfig> = {};\n\n/**\n * addAppConfigs finds any AppConfig objects in the apps in SiteConfig and makes their config\n * available to be used by Apps via getAppConfig(appId) or useAppConfig() functions. This is\n * used at initialization time to process any AppConfigs bundled with the site.\n */\nexport function addAppConfigs() {\n const { apps } = getSiteConfig();\n if (!apps) return;\n\n for (const app of apps) {\n const { appId, config } = app;\n if (config !== undefined) {\n appConfigs[appId] = config;\n }\n }\n\n publish(CONFIG_CHANGED);\n}\n\nexport function getAppConfig(id: string) {\n const { commonAppConfig } = getSiteConfig();\n if (commonAppConfig === undefined) {\n return appConfigs[id];\n }\n return merge({}, commonAppConfig, appConfigs[id]);\n}\n\nexport function mergeAppConfig(id: string, newAppConfig: AppConfig) {\n appConfigs[id] = merge(appConfigs[id], newAppConfig);\n publish(CONFIG_CHANGED);\n}\n\nlet activeRouteRoles: string[] = [];\n\nexport function setActiveRouteRoles(roles: string[]) {\n activeRouteRoles = roles;\n publish(ACTIVE_ROLES_CHANGED);\n}\n\nexport function getActiveRouteRoles() {\n return activeRouteRoles;\n}\n\nconst activeWidgetRoles: Record<string, number> = {};\n\nexport function addActiveWidgetRole(role: string) {\n activeWidgetRoles[role] ??= 0;\n activeWidgetRoles[role] += 1;\n publish(ACTIVE_ROLES_CHANGED);\n}\n\nexport function removeActiveWidgetRole(role: string) {\n if (activeWidgetRoles[role] !== undefined) {\n activeWidgetRoles[role] -= 1;\n }\n if (activeWidgetRoles[role] < 1) {\n delete activeWidgetRoles[role];\n }\n publish(ACTIVE_ROLES_CHANGED);\n}\n\nexport function getActiveWidgetRoles() {\n return Object.entries(activeWidgetRoles)\n .filter(([, count]: [role: string, count: number]) => count !== undefined && count > 0)\n .map(([role]: [role: string, count: number]) => role);\n}\n\n// Gets all active roles from the route roles and widget roles.\nexport function getActiveRoles() {\n return [...getActiveRouteRoles(), ...getActiveWidgetRoles()];\n}\n\n/**\n * Collects all `provides` entries from registered apps that match the given identifier.\n * This enables inter-app data sharing without frontend-base needing to understand the data shape.\n *\n * @param id - The namespaced provides identifier.\n * @returns An array of provided data from all apps that declared data for this identifier.\n */\nexport function getProvides(id: string): unknown[] {\n const { apps } = getSiteConfig();\n if (!apps) return [];\n\n const results: unknown[] = [];\n for (const app of apps) {\n if (app.provides && app.provides[id] !== undefined) {\n results.push(app.provides[id]);\n }\n }\n return results;\n}\n\n/**\n * Collects and flattens all `provides` entries for the given identifier\n * as strings. Each entry can be a single string or a string array; entries\n * of other types are silently skipped.\n *\n * @param id - The namespaced provides identifier.\n * @returns A flat array of strings from all apps that declared data for this identifier.\n */\nexport function getProvidesAsStrings(id: string): string[] {\n return getProvides(id)\n .filter((data): data is string | string[] => typeof data === 'string' || Array.isArray(data))\n .flat();\n}\n\n/**\n * Get an external link URL based on the URL provided. If the passed in URL is overridden in the\n * `externalLinkUrlOverrides` object, it will return the overridden URL. Otherwise, it will return\n * the provided URL.\n *\n *\n * @param {string} url - The default URL.\n * @returns {string} - The external link URL. Defaults to the input URL if not found in the\n * `externalLinkUrlOverrides` object. If the input URL is invalid, '#' is returned.\n *\n * @example\n * import { getExternalLinkUrl } from '@openedx/frontend-base';\n *\n * <Hyperlink\n * destination={getExternalLinkUrl(data.helpLink)}\n * target=\"_blank\"\n * >\n */\nexport function getExternalLinkUrl(url: string): string {\n // Guard against whitespace-only strings\n if (typeof url !== 'string' || !url.trim()) {\n return '#';\n }\n\n const overriddenLinkUrls = getSiteConfig().externalLinkUrlOverrides ?? {};\n return overriddenLinkUrls[url] ?? url;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../runtime/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoGG;;;;;;;;;;;;AAEH,OAAO,OAAO,MAAM,gBAAgB,CAAC;AACrC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,EAEL,gBAAgB,EAEjB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,oBAAoB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,IAAI,UAAU,GAAe;IAC3B,WAAW;IACX,MAAM,EAAE,EAAE;IACV,OAAO,EAAE,EAAE;IACX,QAAQ,EAAE,EAAE;IACZ,QAAQ,EAAE,EAAE;IACZ,SAAS,EAAE,EAAE;IACb,UAAU,EAAE,EAAE;IAEd,WAAW;IACX,WAAW,EAAE,gBAAgB,CAAC,UAAU;IACxC,IAAI,EAAE,EAAE;IACR,cAAc,EAAE,EAAE;IAClB,wBAAwB,EAAE,EAAE;IAC5B,oBAAoB,EAAE,IAAI;IAC1B,KAAK,EAAE,EAAE;IACT,qBAAqB,EAAE,+BAA+B;IACtD,gBAAgB,EAAE,oBAAoB;IACtC,iBAAiB,EAAE,IAAI;IACvB,4BAA4B,EAAE,6BAA6B;IAC3D,yBAAyB,EAAE,gBAAgB;IAC3C,kBAAkB,EAAE,eAAe;IACnC,UAAU,EAAE,IAAI;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;IAeI;AACJ,MAAM,UAAU,aAAa;IAC3B,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,aAAa,CAAC,aAAyB;IACrD,UAAU,GAAG,aAAa,CAAC;IAC3B,OAAO,CAAC,cAAc,CAAC,CAAC;AAC1B,CAAC;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,eAAe,CAC7B,aAAkC,EAClC,UAAkC,EAAE;;IAEpC,MAAM,EAAE,qBAAqB,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAClD,MAAM,EAAE,IAAI,EAAE,OAAO,KAAyB,aAAa,EAAjC,eAAe,UAAK,aAAa,EAArD,QAAqC,CAAgB,CAAC;IAE5D;;qFAEiF;IACjF,UAAU,GAAG,KAAK,CAAC,EAAE,EAAE,UAAU,EAAE,eAAe,CAAC,CAAC;IAEpD,wCAAwC;IACxC,IAAI,CAAC,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,CAAA,EAAE,CAAC;QACrB,OAAO,CAAC,cAAc,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IAED,iDAAiD;IACjD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,UAAU,CAAC,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CACnC,EAAE,EACF,KAAK,CAAC,UAAU,CAAC,IAAI,IAAI,EAAE,EAAE,OAAO,CAAC,EACrC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CACxB,CAAC,CAAC;QACH,OAAO,CAAC,cAAc,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IAED,+CAA+C;IAC/C,mDAAmD;IACnD,IAAI,CAAC,CAAA,MAAA,UAAU,CAAC,IAAI,0CAAE,MAAM,CAAA,EAAE,CAAC;QAC7B,OAAO,CAAC,cAAc,CAAC,CAAC;QACxB,OAAO;IACT,CAAC;IAED,6BAA6B;IAC7B,MAAM,WAAW,GAAG,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAC5C,UAAU,CAAC,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QAC5C,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACtC,IAAI,CAAC,CAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,CAAA,EAAE,CAAC;YACpB,OAAO,GAAG,CAAC;QACb,CAAC;QACD,uCAAY,GAAG,KAAE,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAG;IAClE,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,cAAc,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,GAA8B,EAAE,CAAC;AAEjD;;;;GAIG;AACH,MAAM,UAAU,aAAa;IAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO;IAElB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC;QAC9B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,UAAU,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC;QAC7B,CAAC;IACH,CAAC;IAED,OAAO,CAAC,cAAc,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,MAAM,EAAE,eAAe,EAAE,GAAG,aAAa,EAAE,CAAC;IAC5C,IAAI,eAAe,KAAK,SAAS,EAAE,CAAC;QAClC,OAAO,UAAU,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IACD,OAAO,KAAK,CAAC,EAAE,EAAE,eAAe,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC;AACpD,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,EAAU,EAAE,YAAuB;IAChE,0EAA0E;IAC1E,6DAA6D;IAC7D,UAAU,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,EAAE,YAAY,CAAC,CAAC;IACzD,OAAO,CAAC,cAAc,CAAC,CAAC;AAC1B,CAAC;AAED,IAAI,gBAAgB,GAAa,EAAE,CAAC;AAEpC,MAAM,UAAU,mBAAmB,CAAC,KAAe;IACjD,IAAI,OAAO,CAAC,gBAAgB,EAAE,KAAK,CAAC;QAAE,OAAO;IAC7C,gBAAgB,GAAG,KAAK,CAAC;IACzB,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,mBAAmB;IACjC,OAAO,gBAAgB,CAAC;AAC1B,CAAC;AAED,MAAM,iBAAiB,GAA2B,EAAE,CAAC;AAErD,MAAM,UAAU,mBAAmB,CAAC,IAAY;;IAC9C,iEAAiE;IACjE,MAAM,UAAU,GAAG,CAAC,MAAA,iBAAiB,CAAC,IAAI,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IACtD,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,MAAA,iBAAiB,CAAC,IAAI,CAAC,mCAAI,CAAC,CAAC,GAAG,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU;QAAE,OAAO,CAAC,oBAAoB,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,IAAI,iBAAiB,CAAC,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO;IAClD,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,iBAAiB,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;QAChC,OAAO,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC/B,iEAAiE;QACjE,OAAO,CAAC,oBAAoB,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,OAAO,MAAM,CAAC,OAAO,CAAC,iBAAiB,CAAC;SACrC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,CAAgC,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,GAAG,CAAC,CAAC;SACtF,GAAG,CAAC,CAAC,CAAC,IAAI,CAAgC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;AAC1D,CAAC;AAED,+DAA+D;AAC/D,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,mBAAmB,EAAE,EAAE,GAAG,oBAAoB,EAAE,CAAC,CAAC;AAC/D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,EAAU;IACpC,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;IACjC,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,CAAC;IAErB,MAAM,OAAO,GAAc,EAAE,CAAC;IAC9B,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,EAAU;IAC7C,OAAO,WAAW,CAAC,EAAE,CAAC;SACnB,MAAM,CAAC,CAAC,IAAI,EAA6B,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAC5F,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,kBAAkB,CAAC,GAAW;;IAC5C,wCAAwC;IACxC,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAC3C,OAAO,GAAG,CAAC;IACb,CAAC;IAED,MAAM,kBAAkB,GAAG,MAAA,aAAa,EAAE,CAAC,wBAAwB,mCAAI,EAAE,CAAC;IAC1E,OAAO,MAAA,kBAAkB,CAAC,GAAG,CAAC,mCAAI,GAAG,CAAC;AACxC,CAAC","sourcesContent":["/**\n * #### Import members from **@edx/frontend-base**\n *\n * The configuration module provides utilities for working with an application's configuration\n * document (SiteConfig). Configuration variables can be supplied to the\n * application in three different ways. They are applied in the following order:\n *\n * - Site Configuration File (site.config.tsx)\n * - Initialization Config Handler\n * - Runtime Configuration\n *\n * Last one in wins, and are deep merged together. Variables with the same name defined via the\n * later methods will override any defined using an earlier method. i.e., if a variable is defined\n * in Runtime Configuration, that will override the same variable defined in either of the earlier\n * methods. Configuration defined in a JS file will override any default values below.\n *\n * ##### Site Configuration File\n *\n * Configuration variables can be supplied in a file named site.config.tsx. This file must\n * export either an Object containing configuration variables or a function. The function must\n * return an Object containing configuration variables or, alternately, a promise which resolves to\n * an Object.\n *\n * Using a function or async function allows the configuration to be resolved at runtime (because\n * the function will be executed at runtime). This is not common, and the capability is included\n * for the sake of flexibility.\n *\n * The Site Configuration File is well-suited to extensibility use cases or component overrides,\n * in that the configuration file can depend on any installed JavaScript module. It is also the\n * preferred way of doing build-time configuration if runtime configuration isn't used by your\n * deployment of the platform.\n *\n * Exporting a config object:\n * ```\n * const siteConfig = {\n * lmsBaseUrl: 'http://localhost:18000'\n * };\n *\n * export default siteConfig;\n * ```\n *\n * Exporting a function that returns an object:\n * ```\n * function getSiteConfig() {\n * return {\n * lmsBaseUrl: 'http://localhost:18000'\n * };\n * }\n * ```\n *\n * Exporting a function that returns a promise that resolves to an object:\n * ```\n * function getAsyncSiteConfig() {\n * return new Promise((resolve, reject) => {\n * resolve({\n * lmsBaseUrl: 'http://localhost:18000'\n * });\n * });\n * }\n *\n * export default getAsyncSiteConfig;\n * ```\n *\n * ##### Initialization Config Handler\n *\n * The configuration document can be extended by\n * applications at run-time using a `config` initialization handler. Please see the Initialization\n * documentation for more information on handlers and initialization phases.\n *\n * ```\n * initialize({\n * handlers: {\n * config: () => {\n * mergeSiteConfig({\n * CUSTOM_VARIABLE: 'custom value',\n * lmsBaseUrl: 'http://localhost:18001' // You can override variables, but this is uncommon.\n * }, 'App config override handler');\n * },\n * },\n * });\n * ```\n *\n * ##### Runtime Configuration\n *\n * Configuration variables can also be supplied using the \"runtime configuration\" method, taking\n * advantage of the Micro-frontend Config API in edx-platform. More information on this API can be\n * found in the ADR which introduced it:\n *\n * https://github.com/openedx/edx-platform/blob/master/lms/djangoapps/mfe_config_api/docs/decisions/0001-mfe-config-api.rst\n *\n * The runtime configuration method can be enabled by supplying a runtimeConfigJsonUrl via one of the other\n * two configuration methods above.\n *\n * Runtime configuration is particularly useful if you need to supply different configurations to\n * a single deployment of a micro-frontend, for instance. It is also a perfectly valid alternative\n * to build-time configuration, though it introduces an additional API call to edx-platform on MFE\n * initialization.\n *\n *\n * @module Config\n */\n\nimport isEqual from 'lodash/isEqual';\nimport keyBy from 'lodash/keyBy';\nimport merge from 'lodash/merge';\nimport {\n AppConfig,\n EnvironmentTypes,\n SiteConfig\n} from '../../types';\nimport { ACTIVE_ROLES_CHANGED, CONFIG_CHANGED } from '../constants';\nimport { publish } from '../subscriptions';\n\nlet siteConfig: SiteConfig = {\n // Required\n siteId: '',\n baseUrl: '',\n siteName: '',\n loginUrl: '',\n logoutUrl: '',\n lmsBaseUrl: '',\n\n // Optional\n environment: EnvironmentTypes.PRODUCTION,\n apps: [],\n externalRoutes: [],\n externalLinkUrlOverrides: [],\n runtimeConfigJsonUrl: null,\n theme: {},\n accessTokenCookieName: 'edx-jwt-cookie-header-payload',\n csrfTokenApiPath: '/csrf/api/v1/token',\n ignoredErrorRegex: null,\n languagePreferenceCookieName: 'openedx-language-preference',\n refreshAccessTokenApiPath: '/login_refresh',\n userInfoCookieName: 'edx-user-info',\n segmentKey: null,\n};\n\n/**\n * Getter for the application configuration document. This is synchronous and merely returns a\n * reference to an existing object, and is thus safe to call as often as desired.\n *\n * Example:\n *\n * ```\n * import { getSiteConfig } from '@openedx/frontend-base';\n *\n * const {\n * lmsBaseUrl,\n * } = getSiteConfig();\n * ```\n *\n * @returns {SiteConfig}\n */\nexport function getSiteConfig() {\n return siteConfig;\n}\n\n/**\n * Replaces the existing SiteConfig. This is not commonly used, but can be helpful for tests.\n *\n * Example:\n *\n * ```\n * import { setSiteConfig } from '@openedx/frontend-base';\n *\n * setSiteConfig({\n * lmsBaseUrl, // This is overriding the ENTIRE document - this is not merged in!\n * });\n * ```\n *\n * @param newConfig A replacement SiteConfig which will completely override the current SiteConfig.\n */\nexport function setSiteConfig(newSiteConfig: SiteConfig) {\n siteConfig = newSiteConfig;\n publish(CONFIG_CHANGED);\n}\n\ninterface MergeSiteConfigOptions {\n limitAppMergeToConfig?: boolean,\n}\n\n/**\n * Merges additional configuration values into the site config returned by `getSiteConfig`. Will\n * override any values that exist with the same keys.\n *\n * ```\n * mergeSiteConfig({\n * NEW_KEY: 'new value',\n * OTHER_NEW_KEY: 'other new value',\n * });\n *\n * This function uses lodash.merge internally to merge configuration objects\n * which means they will be merged recursively. See https://lodash.com/docs/latest#merge for\n * documentation on the exact behavior.\n *\n * Apps are merged by appId rather than array index. By default, apps in the incoming config\n * that don't exist in the current config will be added.\n *\n * When `limitAppMergeToConfig` is true:\n * - All non-app parts of the config are still merged normally\n * - Only the `config` property of each existing app is merged\n * - Apps in the incoming config that don't exist in the current config are ignored\n *\n * @param {Object} newSiteConfig\n * @param {Object} options\n * @param {boolean} options.limitAppMergeToConfig - Limit app merging to only the config property of existing apps\n */\nexport function mergeSiteConfig(\n newSiteConfig: Partial<SiteConfig>,\n options: MergeSiteConfigOptions = {}\n) {\n const { limitAppMergeToConfig = false } = options;\n const { apps: newApps, ...restOfNewConfig } = newSiteConfig;\n\n /* `merge({}, ...)` deep-clones into the fresh target, so the new `siteConfig`\n is a brand-new reference and the previous one is never mutated. This is what\n lets React consumers detect that CONFIG_CHANGED actually changed something. */\n siteConfig = merge({}, siteConfig, restOfNewConfig);\n\n // if we don't have new apps, we're done\n if (!newApps?.length) {\n publish(CONFIG_CHANGED);\n return;\n }\n\n // if we're doing a full merge, merge the objects\n if (!limitAppMergeToConfig) {\n siteConfig.apps = Object.values(merge(\n {},\n keyBy(siteConfig.apps || [], 'appId'),\n keyBy(newApps, 'appId')\n ));\n publish(CONFIG_CHANGED);\n return;\n }\n\n // we're doing a config-only merge, if we don't\n // have apps already, we can't update their configs\n if (!siteConfig.apps?.length) {\n publish(CONFIG_CHANGED);\n return;\n }\n\n // handle config-only merging\n const newAppsById = keyBy(newApps, 'appId');\n siteConfig.apps = siteConfig.apps.map((app) => {\n const newApp = newAppsById[app.appId];\n if (!newApp?.config) {\n return app;\n }\n return { ...app, config: merge({}, app.config, newApp.config) };\n });\n\n publish(CONFIG_CHANGED);\n}\n\nconst appConfigs: Record<string, AppConfig> = {};\n\n/**\n * addAppConfigs finds any AppConfig objects in the apps in SiteConfig and makes their config\n * available to be used by Apps via getAppConfig(appId) or useAppConfig() functions. This is\n * used at initialization time to process any AppConfigs bundled with the site.\n */\nexport function addAppConfigs() {\n const { apps } = getSiteConfig();\n if (!apps) return;\n\n for (const app of apps) {\n const { appId, config } = app;\n if (config !== undefined) {\n appConfigs[appId] = config;\n }\n }\n\n publish(CONFIG_CHANGED);\n}\n\nexport function getAppConfig(id: string) {\n const { commonAppConfig } = getSiteConfig();\n if (commonAppConfig === undefined) {\n return appConfigs[id];\n }\n return merge({}, commonAppConfig, appConfigs[id]);\n}\n\nexport function mergeAppConfig(id: string, newAppConfig: AppConfig) {\n // Non-mutating: produce a fresh entry so consumers holding a reference to\n // the previous one don't observe the change underneath them.\n appConfigs[id] = merge({}, appConfigs[id], newAppConfig);\n publish(CONFIG_CHANGED);\n}\n\nlet activeRouteRoles: string[] = [];\n\nexport function setActiveRouteRoles(roles: string[]) {\n if (isEqual(activeRouteRoles, roles)) return;\n activeRouteRoles = roles;\n publish(ACTIVE_ROLES_CHANGED);\n}\n\nexport function getActiveRouteRoles() {\n return activeRouteRoles;\n}\n\nconst activeWidgetRoles: Record<string, number> = {};\n\nexport function addActiveWidgetRole(role: string) {\n // Only publish when the role transitions from absent to present.\n const wasPresent = (activeWidgetRoles[role] ?? 0) > 0;\n activeWidgetRoles[role] = (activeWidgetRoles[role] ?? 0) + 1;\n if (!wasPresent) publish(ACTIVE_ROLES_CHANGED);\n}\n\nexport function removeActiveWidgetRole(role: string) {\n if (activeWidgetRoles[role] === undefined) return;\n activeWidgetRoles[role] -= 1;\n if (activeWidgetRoles[role] < 1) {\n delete activeWidgetRoles[role];\n // Only publish when the role transitions from present to absent.\n publish(ACTIVE_ROLES_CHANGED);\n }\n}\n\nexport function getActiveWidgetRoles() {\n return Object.entries(activeWidgetRoles)\n .filter(([, count]: [role: string, count: number]) => count !== undefined && count > 0)\n .map(([role]: [role: string, count: number]) => role);\n}\n\n// Gets all active roles from the route roles and widget roles.\nexport function getActiveRoles() {\n return [...getActiveRouteRoles(), ...getActiveWidgetRoles()];\n}\n\n/**\n * Collects all `provides` entries from registered apps that match the given identifier.\n * This enables inter-app data sharing without frontend-base needing to understand the data shape.\n *\n * @param id - The namespaced provides identifier.\n * @returns An array of provided data from all apps that declared data for this identifier.\n */\nexport function getProvides(id: string): unknown[] {\n const { apps } = getSiteConfig();\n if (!apps) return [];\n\n const results: unknown[] = [];\n for (const app of apps) {\n if (app.provides && app.provides[id] !== undefined) {\n results.push(app.provides[id]);\n }\n }\n return results;\n}\n\n/**\n * Collects and flattens all `provides` entries for the given identifier\n * as strings. Each entry can be a single string or a string array; entries\n * of other types are silently skipped.\n *\n * @param id - The namespaced provides identifier.\n * @returns A flat array of strings from all apps that declared data for this identifier.\n */\nexport function getProvidesAsStrings(id: string): string[] {\n return getProvides(id)\n .filter((data): data is string | string[] => typeof data === 'string' || Array.isArray(data))\n .flat();\n}\n\n/**\n * Get an external link URL based on the URL provided. If the passed in URL is overridden in the\n * `externalLinkUrlOverrides` object, it will return the overridden URL. Otherwise, it will return\n * the provided URL.\n *\n *\n * @param {string} url - The default URL.\n * @returns {string} - The external link URL. Defaults to the input URL if not found in the\n * `externalLinkUrlOverrides` object. If the input URL is invalid, '#' is returned.\n *\n * @example\n * import { getExternalLinkUrl } from '@openedx/frontend-base';\n *\n * <Hyperlink\n * destination={getExternalLinkUrl(data.helpLink)}\n * target=\"_blank\"\n * >\n */\nexport function getExternalLinkUrl(url: string): string {\n // Guard against whitespace-only strings\n if (typeof url !== 'string' || !url.trim()) {\n return '#';\n }\n\n const overriddenLinkUrls = getSiteConfig().externalLinkUrlOverrides ?? {};\n return overriddenLinkUrls[url] ?? url;\n}\n"]}
|
package/dist/runtime/i18n/lib.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../../runtime/i18n/lib.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,cAAc,CAAC;AACjC,OAAO,SAAS,MAAM,YAAY,CAAC;AAEnC,OAAO,OAAO,MAAM,kBAAkB,CAAC;AAGvC,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAE3C,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,+GAA+G;AAC/G,8FAA8F;AAC9F,mDAAmD;AACnD,MAAM,UAAU,GAAG;IACjB,IAAI,EAAE,yBAAyB;IAC/B,OAAO,EAAE,gCAAgC;IACzC,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,oBAAoB;IAC7B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,kBAAkB;IAC3B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,gBAAgB;IACzB,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,wBAAwB;IACjC,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,mBAAmB;IAC5B,OAAO,EAAE,iBAAiB;IAC1B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,6BAA6B;IACtC,OAAO,EAAE,iBAAiB;IAC1B,IAAI,EAAE,cAAc;IACpB,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,cAAc;IACpB,IAAI,EAAE,uBAAuB;IAC7B,OAAO,EAAE,8BAA8B;IACvC,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,iBAAiB;IACvB,IAAI,EAAE,OAAO;IACb,OAAO,EAAE,eAAe;IACxB,OAAO,EAAE,kBAAkB;IAC3B,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,0BAA0B;CACpC,CAAC;AAEF,IAAI,QAAqG,CAAC;AAE1G;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,CAAC;AAE1C;;GAEG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC;AAErC;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,GAAG,YAAY,UAAU,CAAC;AAExD;;;;GAIG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,wBAAwB,CAAC,IAAI;IAC3C,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5B,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAAM;IACxC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,6FAA6F,CAAC,CAAC;IACjH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,CAAC,KAAK,SAAS,EAAE,CAAC;QACnC,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,QAAQ,CAAC,wBAAwB,CAAC,MAAM,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QAC7D,OAAO,wBAAwB,CAAC,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,MAAe;IACvC,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,mFAAmF,CAAC,CAAC;IACvG,CAAC;IAED,kCAAkC;IAClC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,OAAO,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACrC,CAAC;IACD,4BAA4B;IAE5B,MAAM,EAAE,4BAA4B,EAAE,GAAG,aAAa,EAAE,CAAC;IACzD,IAAI,4BAA4B,EAAE,CAAC;QACjC,MAAM,kBAAkB,GAAG,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QACrE,IAAI,kBAAkB,EAAE,CAAC;YACvB,OAAO,mBAAmB,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED,gCAAgC;IAChC,kGAAkG;IAClG,yCAAyC;IACzC,8EAA8E;IAC9E,OAAO,mBAAmB,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,MAAM;IAC7C,MAAM,aAAa,GAAG,CAAC,IAAI,IAAI,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC;IAEzF,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,uBAAuB,MAAM,EAAE,CAAC,CAAC;IACnD,CAAC;IAED,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AACzF,CAAC;AAED,MAAM,UAAU,wBAAwB;IACtC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACtC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,+DAA+D;IACnF,OAAO,CAAC,IAAI,EAAE,CAAC;IAEf,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAC9B,IAAI,EAAE,MAAM;QACZ,IAAI,EAAE,wBAAwB,CAAC,MAAM,CAAC;KACvC,CAAC,CAAC,CAAC;AACN,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,SAAS,EAAE,CAAC;IACZ,OAAO,CAAC,cAAc,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,MAAM,GAAG,SAAS,EAAE;IAC9C,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CAAC,qFAAqF,CAAC,CAAC;IACzG,CAAC;IAED,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC1B,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,KAAK,CAAC,MAAM;IAC1B,OAAO,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;AACrC,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS;IACvB,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC;QACvB,UAAU,CAAC,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjF,CAAC;SAAM,CAAC;QACN,UAAU,CAAC,QAAQ,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;IACjF,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,WAAW,GAAG,EAAE;IAC5C,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC;IAClF,QAAQ,GAAG,KAAK,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAEjC,OAAO,QAAQ,CAAC;AAClB,CAAC;AAMD;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,OAA6B;IACzD,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;IAE/F,SAAS,EAAE,CAAC;AACd,CAAC","sourcesContent":["import merge from 'lodash.merge';\nimport PropTypes from 'prop-types';\nimport { MessageFormatElement } from 'react-intl';\nimport Cookies from 'universal-cookie';\n\nimport { LocalizedMessages } from '../../types';\nimport { getSiteConfig } from '../config';\nimport { publish } from '../subscriptions';\n\nconst cookies = new Cookies();\n\n// This list is based on https://help.smartling.com/hc/en-us/articles/1260802028830-Right-to-left-RTL-Languages\n// There are very few resources available online outlining the locale codes for RTL languages;\n// If this list is inaccurate, we should change it.\nconst rtlLocales = [\n 'ar', // Arabic (International)\n 'ar-ae', // Arabic (United Arab Emirates)\n 'ar-bh', // Arabic (Bahrain)\n 'ar-dj', // Arabic (Djibouti)\n 'ar-dz', // Arabic (Algeria)\n 'ar-eg', // Arabic (Egypt)\n 'ar-iq', // Arabic (Iraq)\n 'ar-jo', // Arabic (Jordan)\n 'ar-kw', // Arabic (Kuwait)\n 'ar-lb', // Arabic (Lebanon)\n 'ar-ly', // Arabic (Libya)\n 'ar-ma', // Arabic (Morocco)\n 'ar-om', // Arabic (Oman)\n 'ar-qa', // Arabic (Qatar)\n 'ar-sa', // Arabic (Saudi Arabia)\n 'ar-sd', // Arabic (Sudan)\n 'ar-sy', // Arabic (Syria)\n 'ar-tn', // Arabic (Tunisia)\n 'ar-ye', // Arabic (Yemen)\n 'fa', // Persian\n 'fa-af', // Dari/Persian (Afghanistan)\n 'fa-ir', // Persian (Iran)\n 'he', // Hebrew (he)\n 'he-il', // Hebrew\n 'iw', // Hebrew (iw)\n 'kd', // Kurdish (Sorani) RTL\n 'pk-pk', // Panjabi-Shahmuki (Pakistan)\n 'ps', // Pushto; Pashto\n 'ug', // Uighur; Uyghur\n 'ur', // Urdu\n 'ur-in', // Urdu (India)\n 'ur-pk', // Urdu (Pakistan)\n 'yi', // Yiddish\n 'yi-us', // Yiddish (United States)\n];\n\nlet messages: Record<string, Record<string, string> | Record<string, MessageFormatElement[]> | undefined>;\n\n/**\n * @memberof module:Internationalization\n *\n * Prior versions of react-intl (our primary implementation of the i18n service) included a\n * PropTypes-based 'shape' for its `intl` object. This has since been removed. For legacy\n * compatibility, we include an `intlShape` export that is set to PropTypes.object. Usage of this\n * export is deprecated.\n *\n * @deprecated\n */\nexport const intlShape = PropTypes.object;\n\n/**\n * @memberof module:Internationalization\n */\nexport const LOCALE_TOPIC = 'LOCALE';\n\n/**\n * @memberof module:Internationalization\n */\nexport const LOCALE_CHANGED = `${LOCALE_TOPIC}.CHANGED`;\n\n/**\n *\n * @memberof module:Internationalization\n * @returns {Cookies}\n */\nexport function getCookies() {\n return cookies;\n}\n\n/**\n * Some of our dependencies function on primary language subtags, rather than full locales.\n * This function strips a locale down to that first subtag. Depending on the code, this\n * may be 2 or more characters.\n *\n * @param {string} code\n * @memberof module:Internationalization\n */\nexport function getPrimaryLanguageSubtag(code) {\n return code.split('-')[0];\n}\n\n/**\n * Finds the closest supported locale to the one provided. This is done in three steps:\n *\n * 1. Returning the locale itself if its exact language code is supported.\n * 2. Returning the primary language subtag of the language code if it is supported (ar for ar-eg,\n * for instance).\n * 3. Returning 'en' if neither of the above produce a supported locale.\n *\n * @param {string} locale\n * @returns {string}\n * @memberof module:Internationalization\n */\nexport function findSupportedLocale(locale) {\n if (messages === undefined) {\n throw new Error('findSupportedLocale called before configuring i18n. Call configureI18n with messages first.');\n }\n\n if (messages[locale] !== undefined) {\n return locale;\n }\n\n if (messages[getPrimaryLanguageSubtag(locale)] !== undefined) {\n return getPrimaryLanguageSubtag(locale);\n }\n\n return 'en';\n}\n\n/**\n * Get the locale from the cookie or, failing that, the browser setting.\n * Gracefully fall back to a more general primary language subtag or to English (en)\n * if we don't support that language.\n *\n * @param {string|undefined} locale If a locale is provided, returns the closest supported locale. Optional.\n * @throws An error if i18n has not yet been configured.\n * @returns {string}\n * @memberof module:Internationalization\n */\nexport function getLocale(locale?: string) {\n if (messages === null) {\n throw new Error('getLocale called before configuring i18n. Call configureI18n with messages first.');\n }\n\n // 1. Explicit application request\n if (locale !== undefined) {\n return findSupportedLocale(locale);\n }\n // 2. User setting in cookie\n\n const { languagePreferenceCookieName } = getSiteConfig();\n if (languagePreferenceCookieName) {\n const languagePreference = cookies.get(languagePreferenceCookieName);\n if (languagePreference) {\n return findSupportedLocale(languagePreference.toLowerCase());\n }\n }\n\n // 3. Browser language (default)\n // Note that some browers prefer upper case for the region part of the locale, while others don't.\n // Thus the toLowerCase, for consistency.\n // https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language\n return findSupportedLocale(globalThis.navigator.language.toLowerCase());\n}\n\nexport function getLocalizedLanguageName(locale) {\n const localizedName = (new Intl.DisplayNames([locale], { type: 'language' })).of(locale);\n\n if (localizedName === undefined) {\n throw new Error(`Unsupported locale: ${locale}`);\n }\n\n return `${localizedName.charAt(0).toLocaleUpperCase(locale)}${localizedName.slice(1)}`;\n}\n\nexport function getSupportedLanguageList() {\n const locales = Object.keys(messages);\n locales.push('en'); // 'en' is not in the messages object because it's the default.\n locales.sort();\n\n return locales.map((locale) => ({\n code: locale,\n name: getLocalizedLanguageName(locale),\n }));\n}\n\nexport function updateLocale() {\n handleRtl();\n publish(LOCALE_CHANGED);\n}\n\n/**\n * Returns messages for the provided locale, or the user's preferred locale if no argument is\n * provided.\n *\n * @param {string} [locale=getLocale()]\n * @memberof module:Internationalization\n */\nexport function getMessages(locale = getLocale()) {\n if (messages === undefined) {\n throw new Error('getMessages called before configuring i18n. Call configureI18n with messages first.');\n }\n\n return messages[locale];\n}\n\n/**\n * Determines if the provided locale is a right-to-left language.\n *\n * @param {string} locale\n * @memberof module:Internationalization\n */\nexport function isRtl(locale) {\n return rtlLocales.includes(locale);\n}\n\n/**\n * Handles applying the RTL stylesheet and \"dir=rtl\" attribute to the html tag if the current locale\n * is a RTL language.\n *\n * @memberof module:Internationalization\n */\nexport function handleRtl() {\n if (isRtl(getLocale())) {\n globalThis.document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl');\n } else {\n globalThis.document.getElementsByTagName('html')[0].setAttribute('dir', 'ltr');\n }\n}\n\n/**\n *\n *\n * @param {Object} newMessages\n * @returns {Object}\n * @memberof module:Internationalization\n */\nexport function mergeMessages(newMessages = {}) {\n const msgs = Array.isArray(newMessages) ? merge({}, ...newMessages) : newMessages;\n messages = merge(messages, msgs);\n\n return messages;\n}\n\ninterface ConfigureI18nOptions {\n messages: LocalizedMessages[] | LocalizedMessages,\n}\n\n/**\n * Configures the i18n library with messages for your application.\n *\n * Logs a warning if it detects a locale it doesn't expect (as defined by the supportedLocales list\n * above), or if an expected locale is not provided.\n *\n * @param {Object} options\n * @param {Object} options.messages\n * @memberof module:Internationalization\n */\nexport function configureI18n(options: ConfigureI18nOptions) {\n messages = Array.isArray(options.messages) ? merge({}, ...options.messages) : options.messages;\n\n handleRtl();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../../../runtime/i18n/lib.ts"],"names":[],"mappings":"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","sourcesContent":["import merge from 'lodash/merge';\nimport PropTypes from 'prop-types';\nimport { MessageFormatElement } from 'react-intl';\nimport Cookies from 'universal-cookie';\n\nimport { LocalizedMessages } from '../../types';\nimport { getSiteConfig } from '../config';\nimport { publish } from '../subscriptions';\n\nconst cookies = new Cookies();\n\n// This list is based on https://help.smartling.com/hc/en-us/articles/1260802028830-Right-to-left-RTL-Languages\n// There are very few resources available online outlining the locale codes for RTL languages;\n// If this list is inaccurate, we should change it.\nconst rtlLocales = [\n 'ar', // Arabic (International)\n 'ar-ae', // Arabic (United Arab Emirates)\n 'ar-bh', // Arabic (Bahrain)\n 'ar-dj', // Arabic (Djibouti)\n 'ar-dz', // Arabic (Algeria)\n 'ar-eg', // Arabic (Egypt)\n 'ar-iq', // Arabic (Iraq)\n 'ar-jo', // Arabic (Jordan)\n 'ar-kw', // Arabic (Kuwait)\n 'ar-lb', // Arabic (Lebanon)\n 'ar-ly', // Arabic (Libya)\n 'ar-ma', // Arabic (Morocco)\n 'ar-om', // Arabic (Oman)\n 'ar-qa', // Arabic (Qatar)\n 'ar-sa', // Arabic (Saudi Arabia)\n 'ar-sd', // Arabic (Sudan)\n 'ar-sy', // Arabic (Syria)\n 'ar-tn', // Arabic (Tunisia)\n 'ar-ye', // Arabic (Yemen)\n 'fa', // Persian\n 'fa-af', // Dari/Persian (Afghanistan)\n 'fa-ir', // Persian (Iran)\n 'he', // Hebrew (he)\n 'he-il', // Hebrew\n 'iw', // Hebrew (iw)\n 'kd', // Kurdish (Sorani) RTL\n 'pk-pk', // Panjabi-Shahmuki (Pakistan)\n 'ps', // Pushto; Pashto\n 'ug', // Uighur; Uyghur\n 'ur', // Urdu\n 'ur-in', // Urdu (India)\n 'ur-pk', // Urdu (Pakistan)\n 'yi', // Yiddish\n 'yi-us', // Yiddish (United States)\n];\n\nlet messages: Record<string, Record<string, string> | Record<string, MessageFormatElement[]> | undefined>;\n\n/**\n * @memberof module:Internationalization\n *\n * Prior versions of react-intl (our primary implementation of the i18n service) included a\n * PropTypes-based 'shape' for its `intl` object. This has since been removed. For legacy\n * compatibility, we include an `intlShape` export that is set to PropTypes.object. Usage of this\n * export is deprecated.\n *\n * @deprecated\n */\nexport const intlShape = PropTypes.object;\n\n/**\n * @memberof module:Internationalization\n */\nexport const LOCALE_TOPIC = 'LOCALE';\n\n/**\n * @memberof module:Internationalization\n */\nexport const LOCALE_CHANGED = `${LOCALE_TOPIC}.CHANGED`;\n\n/**\n *\n * @memberof module:Internationalization\n * @returns {Cookies}\n */\nexport function getCookies() {\n return cookies;\n}\n\n/**\n * Some of our dependencies function on primary language subtags, rather than full locales.\n * This function strips a locale down to that first subtag. Depending on the code, this\n * may be 2 or more characters.\n *\n * @param {string} code\n * @memberof module:Internationalization\n */\nexport function getPrimaryLanguageSubtag(code) {\n return code.split('-')[0];\n}\n\n/**\n * Finds the closest supported locale to the one provided. This is done in three steps:\n *\n * 1. Returning the locale itself if its exact language code is supported.\n * 2. Returning the primary language subtag of the language code if it is supported (ar for ar-eg,\n * for instance).\n * 3. Returning 'en' if neither of the above produce a supported locale.\n *\n * @param {string} locale\n * @returns {string}\n * @memberof module:Internationalization\n */\nexport function findSupportedLocale(locale) {\n if (messages === undefined) {\n throw new Error('findSupportedLocale called before configuring i18n. Call configureI18n with messages first.');\n }\n\n if (messages[locale] !== undefined) {\n return locale;\n }\n\n if (messages[getPrimaryLanguageSubtag(locale)] !== undefined) {\n return getPrimaryLanguageSubtag(locale);\n }\n\n return 'en';\n}\n\n/**\n * Get the locale from the cookie or, failing that, the browser setting.\n * Gracefully fall back to a more general primary language subtag or to English (en)\n * if we don't support that language.\n *\n * @param {string|undefined} locale If a locale is provided, returns the closest supported locale. Optional.\n * @throws An error if i18n has not yet been configured.\n * @returns {string}\n * @memberof module:Internationalization\n */\nexport function getLocale(locale?: string) {\n if (messages === null) {\n throw new Error('getLocale called before configuring i18n. Call configureI18n with messages first.');\n }\n\n // 1. Explicit application request\n if (locale !== undefined) {\n return findSupportedLocale(locale);\n }\n // 2. User setting in cookie\n\n const { languagePreferenceCookieName } = getSiteConfig();\n if (languagePreferenceCookieName) {\n const languagePreference = cookies.get(languagePreferenceCookieName);\n if (languagePreference) {\n return findSupportedLocale(languagePreference.toLowerCase());\n }\n }\n\n // 3. Browser language (default)\n // Note that some browers prefer upper case for the region part of the locale, while others don't.\n // Thus the toLowerCase, for consistency.\n // https://developer.mozilla.org/en-US/docs/Web/API/NavigatorLanguage/language\n return findSupportedLocale(globalThis.navigator.language.toLowerCase());\n}\n\nexport function getLocalizedLanguageName(locale) {\n const localizedName = (new Intl.DisplayNames([locale], { type: 'language' })).of(locale);\n\n if (localizedName === undefined) {\n throw new Error(`Unsupported locale: ${locale}`);\n }\n\n return `${localizedName.charAt(0).toLocaleUpperCase(locale)}${localizedName.slice(1)}`;\n}\n\nexport function getSupportedLanguageList() {\n const locales = Object.keys(messages);\n locales.push('en'); // 'en' is not in the messages object because it's the default.\n locales.sort();\n\n return locales.map((locale) => ({\n code: locale,\n name: getLocalizedLanguageName(locale),\n }));\n}\n\nexport function updateLocale() {\n handleRtl();\n publish(LOCALE_CHANGED);\n}\n\n/**\n * Returns messages for the provided locale, or the user's preferred locale if no argument is\n * provided.\n *\n * @param {string} [locale=getLocale()]\n * @memberof module:Internationalization\n */\nexport function getMessages(locale = getLocale()) {\n if (messages === undefined) {\n throw new Error('getMessages called before configuring i18n. Call configureI18n with messages first.');\n }\n\n return messages[locale];\n}\n\n/**\n * Determines if the provided locale is a right-to-left language.\n *\n * @param {string} locale\n * @memberof module:Internationalization\n */\nexport function isRtl(locale) {\n return rtlLocales.includes(locale);\n}\n\n/**\n * Handles applying the RTL stylesheet and \"dir=rtl\" attribute to the html tag if the current locale\n * is a RTL language.\n *\n * @memberof module:Internationalization\n */\nexport function handleRtl() {\n if (isRtl(getLocale())) {\n globalThis.document.getElementsByTagName('html')[0].setAttribute('dir', 'rtl');\n } else {\n globalThis.document.getElementsByTagName('html')[0].setAttribute('dir', 'ltr');\n }\n}\n\n/**\n *\n *\n * @param {Object} newMessages\n * @returns {Object}\n * @memberof module:Internationalization\n */\nexport function mergeMessages(newMessages = {}) {\n const msgs = Array.isArray(newMessages) ? merge({}, ...newMessages) : newMessages;\n messages = merge(messages, msgs);\n\n return messages;\n}\n\ninterface ConfigureI18nOptions {\n messages: LocalizedMessages[] | LocalizedMessages,\n}\n\n/**\n * Configures the i18n library with messages for your application.\n *\n * Logs a warning if it detects a locale it doesn't expect (as defined by the supportedLocales list\n * above), or if an expected locale is not provided.\n *\n * @param {Object} options\n * @param {Object} options.messages\n * @memberof module:Internationalization\n */\nexport function configureI18n(options: ConfigureI18nOptions) {\n messages = Array.isArray(options.messages) ? merge({}, ...options.messages) : options.messages;\n\n handleRtl();\n}\n"]}
|
|
@@ -2,5 +2,5 @@ import { ReactNode } from 'react';
|
|
|
2
2
|
interface CombinedAppProviderProps {
|
|
3
3
|
children: ReactNode;
|
|
4
4
|
}
|
|
5
|
-
export default function CombinedAppProvider({ children }: CombinedAppProviderProps):
|
|
5
|
+
export default function CombinedAppProvider({ children }: CombinedAppProviderProps): ReactNode;
|
|
6
6
|
export {};
|
|
@@ -1,24 +1,20 @@
|
|
|
1
|
-
import { jsx as _jsx
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useMemo } from 'react';
|
|
2
3
|
import { getSiteConfig } from '../config';
|
|
3
|
-
const combineProviders = (providers) => {
|
|
4
|
-
return providers.reduce((AccumulatedProviders, CurrentProvider) => {
|
|
5
|
-
// eslint-disable-next-line react/prop-types
|
|
6
|
-
const CombinedProvider = ({ children }) => (_jsx(AccumulatedProviders, { children: _jsx(CurrentProvider, { children: children }) }));
|
|
7
|
-
return CombinedProvider;
|
|
8
|
-
}, ({ children }) => _jsx(_Fragment, { children: children }));
|
|
9
|
-
};
|
|
10
4
|
export default function CombinedAppProvider({ children }) {
|
|
11
5
|
const { apps } = getSiteConfig();
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
apps
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
6
|
+
const providers = useMemo(() => {
|
|
7
|
+
const list = [];
|
|
8
|
+
if (apps) {
|
|
9
|
+
apps.forEach((app) => {
|
|
10
|
+
if (Array.isArray(app.providers)) {
|
|
11
|
+
list.push(...app.providers);
|
|
12
|
+
}
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return list;
|
|
16
|
+
}, [apps]);
|
|
17
|
+
return providers.reduceRight((acc, Provider) => _jsx(Provider, { children: acc }), children);
|
|
22
18
|
}
|
|
23
19
|
;
|
|
24
20
|
//# sourceMappingURL=CombinedAppProvider.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CombinedAppProvider.js","sourceRoot":"","sources":["../../../runtime/react/CombinedAppProvider.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"CombinedAppProvider.js","sourceRoot":"","sources":["../../../runtime/react/CombinedAppProvider.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAa,OAAO,EAAE,MAAM,OAAO,CAAC;AAE3C,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAM1C,MAAM,CAAC,OAAO,UAAU,mBAAmB,CAAC,EAAE,QAAQ,EAA4B;IAChF,MAAM,EAAE,IAAI,EAAE,GAAG,aAAa,EAAE,CAAC;IAEjC,MAAM,SAAS,GAAG,OAAO,CAAgB,GAAG,EAAE;QAC5C,MAAM,IAAI,GAAkB,EAAE,CAAC;QAC/B,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,OAAO,CAAC,CAAC,GAAQ,EAAE,EAAE;gBACxB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;oBACjC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC9B,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;IAEX,OAAO,SAAS,CAAC,WAAW,CAC1B,CAAC,GAAG,EAAE,QAAQ,EAAE,EAAE,CAAC,KAAC,QAAQ,cAAE,GAAG,GAAY,EAC7C,QAAQ,CACT,CAAC;AACJ,CAAC;AAAA,CAAC","sourcesContent":["import { ReactNode, useMemo } from 'react';\nimport { App, AppProvider } from '../../types';\nimport { getSiteConfig } from '../config';\n\ninterface CombinedAppProviderProps {\n children: ReactNode,\n}\n\nexport default function CombinedAppProvider({ children }: CombinedAppProviderProps) {\n const { apps } = getSiteConfig();\n\n const providers = useMemo<AppProvider[]>(() => {\n const list: AppProvider[] = [];\n if (apps) {\n apps.forEach((app: App) => {\n if (Array.isArray(app.providers)) {\n list.push(...app.providers);\n }\n });\n }\n return list;\n }, [apps]);\n\n return providers.reduceRight<ReactNode>(\n (acc, Provider) => <Provider>{acc}</Provider>,\n children,\n );\n};\n"]}
|
|
@@ -1,12 +1,15 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
2
|
import { getActiveRoles } from '../../config';
|
|
3
3
|
import { ACTIVE_ROLES_CHANGED } from '../../constants';
|
|
4
4
|
import useSiteEvent from './useSiteEvent';
|
|
5
5
|
const useActiveRoles = () => {
|
|
6
6
|
const [roles, setRoles] = useState(getActiveRoles());
|
|
7
|
-
useSiteEvent
|
|
7
|
+
/* Stabilize the callback so useSiteEvent doesn't unsubscribe + resubscribe on every render.
|
|
8
|
+
Every Slot in the tree subscribes via this hook, so the churn would be tree-wide. */
|
|
9
|
+
const onChange = useCallback(() => {
|
|
8
10
|
setRoles(getActiveRoles());
|
|
9
|
-
});
|
|
11
|
+
}, []);
|
|
12
|
+
useSiteEvent(ACTIVE_ROLES_CHANGED, onChange);
|
|
10
13
|
return roles;
|
|
11
14
|
};
|
|
12
15
|
export default useActiveRoles;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActiveRoles.js","sourceRoot":"","sources":["../../../../runtime/react/hooks/useActiveRoles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"useActiveRoles.js","sourceRoot":"","sources":["../../../../runtime/react/hooks/useActiveRoles.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC9C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAC9C,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,YAAY,MAAM,gBAAgB,CAAC;AAE1C,MAAM,cAAc,GAAG,GAAG,EAAE;IAC1B,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAW,cAAc,EAAE,CAAC,CAAC;IAC/D;2FACuF;IACvF,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,EAAE;QAChC,QAAQ,CAAC,cAAc,EAAE,CAAC,CAAC;IAC7B,CAAC,EAAE,EAAE,CAAC,CAAC;IACP,YAAY,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC;IAE7C,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEF,eAAe,cAAc,CAAC","sourcesContent":["import { useCallback, useState } from 'react';\nimport { getActiveRoles } from '../../config';\nimport { ACTIVE_ROLES_CHANGED } from '../../constants';\nimport useSiteEvent from './useSiteEvent';\n\nconst useActiveRoles = () => {\n const [roles, setRoles] = useState<string[]>(getActiveRoles());\n /* Stabilize the callback so useSiteEvent doesn't unsubscribe + resubscribe on every render.\n Every Slot in the tree subscribes via this hook, so the churn would be tree-wide. */\n const onChange = useCallback(() => {\n setRoles(getActiveRoles());\n }, []);\n useSiteEvent(ACTIVE_ROLES_CHANGED, onChange);\n\n return roles;\n};\n\nexport default useActiveRoles;\n"]}
|
|
@@ -1,14 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useEffect } from 'react';
|
|
2
2
|
import { useMatches } from 'react-router';
|
|
3
3
|
import { setActiveRouteRoles } from '../../config';
|
|
4
4
|
import { isRoleRouteObject } from '../../routing';
|
|
5
5
|
const useActiveRouteRoleWatcher = () => {
|
|
6
6
|
const matches = useMatches();
|
|
7
|
-
|
|
8
|
-
const findActiveRouteRoles = useCallback(() => {
|
|
9
|
-
// Starts with the widget roles and adds the others in.
|
|
7
|
+
useEffect(() => {
|
|
10
8
|
const roles = [];
|
|
11
|
-
// Route roles
|
|
12
9
|
for (const match of matches) {
|
|
13
10
|
if (isRoleRouteObject(match)) {
|
|
14
11
|
for (const role of match.handle.roles) {
|
|
@@ -18,11 +15,8 @@ const useActiveRouteRoleWatcher = () => {
|
|
|
18
15
|
}
|
|
19
16
|
}
|
|
20
17
|
}
|
|
21
|
-
|
|
18
|
+
setActiveRouteRoles(roles);
|
|
22
19
|
}, [matches]);
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
setActiveRouteRoles(findActiveRouteRoles());
|
|
25
|
-
}, [matches, findActiveRouteRoles]);
|
|
26
20
|
};
|
|
27
21
|
export default useActiveRouteRoleWatcher;
|
|
28
22
|
//# sourceMappingURL=useActiveRouteRoleWatcher.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useActiveRouteRoleWatcher.js","sourceRoot":"","sources":["../../../../runtime/react/hooks/useActiveRouteRoleWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"useActiveRouteRoleWatcher.js","sourceRoot":"","sources":["../../../../runtime/react/hooks/useActiveRouteRoleWatcher.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,yBAAyB,GAAG,GAAG,EAAE;IACrC,MAAM,OAAO,GAAG,UAAU,EAAE,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,IAAI,iBAAiB,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC7B,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBACtC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;wBAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBACnB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;AAChB,CAAC,CAAC;AAEF,eAAe,yBAAyB,CAAC","sourcesContent":["import { useEffect } from 'react';\nimport { useMatches } from 'react-router';\nimport { setActiveRouteRoles } from '../../config';\nimport { isRoleRouteObject } from '../../routing';\n\nconst useActiveRouteRoleWatcher = () => {\n const matches = useMatches();\n\n useEffect(() => {\n const roles: string[] = [];\n for (const match of matches) {\n if (isRoleRouteObject(match)) {\n for (const role of match.handle.roles) {\n if (!roles.includes(role)) {\n roles.push(role);\n }\n }\n }\n }\n setActiveRouteRoles(roles);\n }, [matches]);\n};\n\nexport default useActiveRouteRoleWatcher;\n"]}
|
|
@@ -6,5 +6,6 @@ interface SlotProps {
|
|
|
6
6
|
layout?: ComponentType | ReactNode;
|
|
7
7
|
[key: string]: unknown;
|
|
8
8
|
}
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
declare function Slot({ id, idAliases, children, layout, ...props }: SlotProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
declare const _default: import("react").MemoExoticComponent<typeof Slot>;
|
|
11
|
+
export default _default;
|
|
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
12
|
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
13
|
-
import { createElement, isValidElement } from 'react';
|
|
13
|
+
import { createElement, isValidElement, memo } from 'react';
|
|
14
14
|
import DefaultSlotLayout from './layout/DefaultSlotLayout';
|
|
15
15
|
import { useLayoutForSlotId } from './layout/hooks';
|
|
16
16
|
import SlotContext from './SlotContext';
|
|
@@ -28,8 +28,10 @@ function SlotRenderer({ layout }) {
|
|
|
28
28
|
}
|
|
29
29
|
return _jsx(_Fragment, { children: layoutElement });
|
|
30
30
|
}
|
|
31
|
-
|
|
31
|
+
function Slot(_a) {
|
|
32
32
|
var { id, idAliases, children, layout = DefaultSlotLayout } = _a, props = __rest(_a, ["id", "idAliases", "children", "layout"]);
|
|
33
33
|
return (_jsx(SlotContext.Provider, { value: Object.assign({ id, idAliases, children }, props), children: _jsx(SlotRenderer, { layout: layout }) }));
|
|
34
34
|
}
|
|
35
|
+
/* memo so parent re-renders don't cascade through Slot when props are shallow-equal. */
|
|
36
|
+
export default memo(Slot);
|
|
35
37
|
//# sourceMappingURL=Slot.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Slot.js","sourceRoot":"","sources":["../../../runtime/slots/Slot.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAiB,aAAa,EAAE,cAAc,EAAa,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"Slot.js","sourceRoot":"","sources":["../../../runtime/slots/Slot.tsx"],"names":[],"mappings":";;;;;;;;;;;;AAAA,OAAO,EAAiB,aAAa,EAAE,cAAc,EAAE,IAAI,EAAa,MAAM,OAAO,CAAC;AACtF,OAAO,iBAAiB,MAAM,4BAA4B,CAAC;AAC3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAUzC,SAAS,YAAY,CAAC,EAAE,MAAM,EAAyC;IACrE,MAAM,EAAE,EAAE,EAAE,GAAG,cAAc,EAAE,CAAC;IAChC,IAAI,aAAa,GAA8B,MAAM,CAAC;IAEtD,MAAM,cAAc,GAAG,kBAAkB,CAAC,EAAE,CAAC,CAAC;IAE9C,yDAAyD;IACzD,IAAI,cAAc,IAAI,cAAc,KAAK,IAAI,IAAI,cAAc,KAAK,SAAS,IAAI,OAAO,cAAc,KAAK,SAAS,EAAE,CAAC;QACrH,aAAa,GAAG,cAAc,CAAC;IACjC,CAAC;IAED,IAAI,CAAC,cAAc,CAAC,aAAa,CAAC,EAAE,CAAC;QACnC,aAAa,GAAG,aAAa,CAAC,aAA8B,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,4BAAG,aAAa,GAAI,CAAC;AAC9B,CAAC;AAED,SAAS,IAAI,CAAC,EAA4E;QAA5E,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,GAAG,iBAAiB,OAAuB,EAAlB,KAAK,cAA/D,yCAAiE,CAAF;IAC3E,OAAO,CACL,KAAC,WAAW,CAAC,QAAQ,IAAC,KAAK,kBAAI,EAAE,EAAE,SAAS,EAAE,QAAQ,IAAK,KAAK,aAC9D,KAAC,YAAY,IAAC,MAAM,EAAE,MAAM,GAAI,GACX,CACxB,CAAC;AACJ,CAAC;AAED,wFAAwF;AACxF,eAAe,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["import { ComponentType, createElement, isValidElement, memo, ReactNode } from 'react';\nimport DefaultSlotLayout from './layout/DefaultSlotLayout';\nimport { useLayoutForSlotId } from './layout/hooks';\nimport SlotContext from './SlotContext';\nimport { useSlotContext } from './hooks';\n\ninterface SlotProps {\n id: string,\n idAliases?: string[],\n children?: ReactNode,\n layout?: ComponentType | ReactNode,\n [key: string]: unknown,\n}\n\nfunction SlotRenderer({ layout }: { layout: ComponentType | ReactNode }) {\n const { id } = useSlotContext();\n let layoutElement: ComponentType | ReactNode = layout;\n\n const overrideLayout = useLayoutForSlotId(id);\n\n // Weed out any ReactNode types that aren't actually JSX.\n if (overrideLayout && overrideLayout !== null && overrideLayout !== undefined && typeof overrideLayout !== 'boolean') {\n layoutElement = overrideLayout;\n }\n\n if (!isValidElement(layoutElement)) {\n layoutElement = createElement(layoutElement as ComponentType);\n }\n\n return <>{layoutElement}</>;\n}\n\nfunction Slot({ id, idAliases, children, layout = DefaultSlotLayout, ...props }: SlotProps) {\n return (\n <SlotContext.Provider value={{ id, idAliases, children, ...props }}>\n <SlotRenderer layout={layout} />\n </SlotContext.Provider>\n );\n}\n\n/* memo so parent re-renders don't cascade through Slot when props are shallow-equal. */\nexport default memo(Slot);\n"]}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
-
import { SlotOperation } from './types';
|
|
2
1
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* config as it changes.
|
|
2
|
+
* Resolves the operations registered for a given slot id (plus any aliases),
|
|
3
|
+
* prepended with a default-content operation built from the slot's children.
|
|
6
4
|
*/
|
|
7
|
-
export declare function useSlotOperations(id: string): SlotOperation[];
|
|
5
|
+
export declare function useSlotOperations(id: string): import("./types").SlotOperation[];
|
|
8
6
|
export declare function useSlotContext(): {
|
|
9
7
|
[key: string]: unknown;
|
|
10
8
|
id: string;
|
|
@@ -1,27 +1,17 @@
|
|
|
1
|
-
import { useContext,
|
|
2
|
-
import { useLocation } from 'react-router-dom';
|
|
1
|
+
import { useContext, useMemo } from 'react';
|
|
3
2
|
import { getSlotOperations } from './utils';
|
|
4
3
|
import SlotContext from './SlotContext';
|
|
5
4
|
import { createWidgetAppendOperation } from './widget';
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* config as it changes.
|
|
6
|
+
* Resolves the operations registered for a given slot id (plus any aliases),
|
|
7
|
+
* prepended with a default-content operation built from the slot's children.
|
|
10
8
|
*/
|
|
11
9
|
export function useSlotOperations(id) {
|
|
12
10
|
const { children, idAliases } = useSlotContext();
|
|
13
|
-
|
|
14
|
-
const [operations, setOperations] = useState([]);
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
// Setting default content has to happen inside `useEffect()` so that re-renders only happen
|
|
17
|
-
// when [children] props change. This avoids an endless render loop. After all, the whole
|
|
18
|
-
// point of a slot is to modify its children via slot operations.
|
|
11
|
+
return useMemo(() => {
|
|
19
12
|
const defaultOperation = createWidgetAppendOperation('defaultContent', id, children);
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
// roles (and thus, changes in what conditional widgets are shown) properly.
|
|
23
|
-
}, [id, children, idAliases, location]);
|
|
24
|
-
return operations;
|
|
13
|
+
return getSlotOperations([id, ...(idAliases !== null && idAliases !== void 0 ? idAliases : [])], defaultOperation);
|
|
14
|
+
}, [id, children, idAliases]);
|
|
25
15
|
}
|
|
26
16
|
export function useSlotContext() {
|
|
27
17
|
return useContext(SlotContext);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../runtime/slots/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../runtime/slots/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAE5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,WAAW,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAEvD;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAU;IAC1C,MAAM,EAAE,QAAQ,EAAE,SAAS,EAAE,GAAG,cAAc,EAAE,CAAC;IAEjD,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,MAAM,gBAAgB,GAAG,2BAA2B,CAAC,gBAAgB,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QACrF,OAAO,iBAAiB,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,SAAS,aAAT,SAAS,cAAT,SAAS,GAAI,EAAE,CAAC,CAAC,EAAE,gBAAgB,CAAC,CAAC;IACzE,CAAC,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC","sourcesContent":["import { useContext, useMemo } from 'react';\n\nimport { getSlotOperations } from './utils';\nimport SlotContext from './SlotContext';\nimport { createWidgetAppendOperation } from './widget';\n\n/**\n * Resolves the operations registered for a given slot id (plus any aliases),\n * prepended with a default-content operation built from the slot's children.\n */\nexport function useSlotOperations(id: string) {\n const { children, idAliases } = useSlotContext();\n\n return useMemo(() => {\n const defaultOperation = createWidgetAppendOperation('defaultContent', id, children);\n return getSlotOperations([id, ...(idAliases ?? [])], defaultOperation);\n }, [id, children, idAliases]);\n}\n\nexport function useSlotContext() {\n return useContext(SlotContext);\n}\n"]}
|
|
@@ -3,8 +3,7 @@ export declare function useLayoutForSlotId(id: string): ReactNode | ComponentTyp
|
|
|
3
3
|
/**
|
|
4
4
|
* useLayoutOptions iterates through the slot's operations to find any which are "layout
|
|
5
5
|
* options" operations. It merges these into a single object and returns them - operations are
|
|
6
|
-
* merged in declaration order, meaning last one in wins.
|
|
7
|
-
* re-render when the options change.
|
|
6
|
+
* merged in declaration order, meaning last one in wins.
|
|
8
7
|
*/
|
|
9
8
|
export declare function useLayoutOptions(): Record<string, unknown>;
|
|
10
9
|
export declare function useLayoutOptionsForId(id: string): Record<string, unknown>;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
import useActiveRoles from '../../react/hooks/useActiveRoles';
|
|
2
3
|
import { useSlotContext, useSlotOperations } from '../hooks';
|
|
3
4
|
import { isSlotOperationConditionSatisfied } from '../utils';
|
|
4
5
|
import { isLayoutOperation, isLayoutOptionsOperation, isLayoutReplaceOperation } from './utils';
|
|
@@ -10,10 +11,11 @@ function hasLayoutElementProps(operation) {
|
|
|
10
11
|
}
|
|
11
12
|
export function useLayoutForSlotId(id) {
|
|
12
13
|
const operations = useSlotOperations(id);
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
const activeRoles = useActiveRoles();
|
|
15
|
+
return useMemo(() => {
|
|
16
|
+
let layoutElement = null;
|
|
17
|
+
for (const operation of operations) {
|
|
18
|
+
if (isSlotOperationConditionSatisfied(operation, activeRoles) && isLayoutReplaceOperation(operation)) {
|
|
17
19
|
if (hasLayoutComponentProps(operation)) {
|
|
18
20
|
layoutElement = operation.component;
|
|
19
21
|
}
|
|
@@ -22,14 +24,13 @@ export function useLayoutForSlotId(id) {
|
|
|
22
24
|
}
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
return layoutElement;
|
|
28
|
+
}, [operations, activeRoles]);
|
|
27
29
|
}
|
|
28
30
|
/**
|
|
29
31
|
* useLayoutOptions iterates through the slot's operations to find any which are "layout
|
|
30
32
|
* options" operations. It merges these into a single object and returns them - operations are
|
|
31
|
-
* merged in declaration order, meaning last one in wins.
|
|
32
|
-
* re-render when the options change.
|
|
33
|
+
* merged in declaration order, meaning last one in wins.
|
|
33
34
|
*/
|
|
34
35
|
export function useLayoutOptions() {
|
|
35
36
|
const { id } = useSlotContext();
|
|
@@ -37,21 +38,15 @@ export function useLayoutOptions() {
|
|
|
37
38
|
}
|
|
38
39
|
export function useLayoutOptionsForId(id) {
|
|
39
40
|
const operations = useSlotOperations(id);
|
|
40
|
-
const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
if (isLayoutOptionsOperation(operation)) {
|
|
47
|
-
nextOptions = Object.assign(Object.assign({}, nextOptions), operation.options);
|
|
48
|
-
}
|
|
49
|
-
}
|
|
41
|
+
const activeRoles = useActiveRoles();
|
|
42
|
+
return useMemo(() => {
|
|
43
|
+
let options = {};
|
|
44
|
+
for (const operation of operations) {
|
|
45
|
+
if (isSlotOperationConditionSatisfied(operation, activeRoles) && isLayoutOptionsOperation(operation)) {
|
|
46
|
+
options = Object.assign(Object.assign({}, options), operation.options);
|
|
50
47
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}, [operations]);
|
|
55
|
-
return options;
|
|
48
|
+
}
|
|
49
|
+
return options;
|
|
50
|
+
}, [operations, activeRoles]);
|
|
56
51
|
}
|
|
57
52
|
//# sourceMappingURL=hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../runtime/slots/layout/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../runtime/slots/layout/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,EAA4B,OAAO,EAAE,MAAM,OAAO,CAAC;AAC1D,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAEhG,SAAS,uBAAuB,CAAC,SAA0B;IACzD,OAAO,iBAAiB,CAAC,SAAS,CAAC,IAAI,WAAW,IAAI,SAAS,CAAC;AAClE,CAAC;AAED,SAAS,qBAAqB,CAAC,SAA0B;IACvD,OAAO,iBAAiB,CAAC,SAAS,CAAC,IAAI,SAAS,IAAI,SAAS,CAAC;AAChE,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,EAAU;IAC3C,MAAM,UAAU,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,OAAO,OAAO,CAA4B,GAAG,EAAE;QAC7C,IAAI,aAAa,GAA8B,IAAI,CAAC;QACpD,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,iCAAiC,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,wBAAwB,CAAC,SAAS,CAAC,EAAE,CAAC;gBACrG,IAAI,uBAAuB,CAAC,SAAS,CAAC,EAAE,CAAC;oBACvC,aAAa,GAAG,SAAS,CAAC,SAAS,CAAC;gBACtC,CAAC;qBAAM,IAAI,qBAAqB,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC5C,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC;gBACpC,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,aAAa,CAAC;IACvB,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;AAChC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,EAAE,EAAE,GAAG,cAAc,EAAE,CAAC;IAChC,OAAO,qBAAqB,CAAC,EAAE,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,EAAU;IAC9C,MAAM,UAAU,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,OAAO,GAA4B,EAAE,CAAC;QAC1C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,iCAAiC,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,wBAAwB,CAAC,SAAS,CAAC,EAAE,CAAC;gBACrG,OAAO,mCAAQ,OAAO,GAAK,SAAS,CAAC,OAAO,CAAE,CAAC;YACjD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;AAChC,CAAC","sourcesContent":["import { ComponentType, ReactNode, useMemo } from 'react';\nimport useActiveRoles from '../../react/hooks/useActiveRoles';\nimport { useSlotContext, useSlotOperations } from '../hooks';\nimport { isSlotOperationConditionSatisfied } from '../utils';\nimport { LayoutComponentProps, LayoutElementProps, LayoutOperation } from './types';\nimport { isLayoutOperation, isLayoutOptionsOperation, isLayoutReplaceOperation } from './utils';\n\nfunction hasLayoutComponentProps(operation: LayoutOperation): operation is (LayoutOperation & LayoutComponentProps) {\n return isLayoutOperation(operation) && 'component' in operation;\n}\n\nfunction hasLayoutElementProps(operation: LayoutOperation): operation is (LayoutOperation & LayoutElementProps) {\n return isLayoutOperation(operation) && 'element' in operation;\n}\n\nexport function useLayoutForSlotId(id: string) {\n const operations = useSlotOperations(id);\n const activeRoles = useActiveRoles();\n\n return useMemo<ReactNode | ComponentType>(() => {\n let layoutElement: ReactNode | ComponentType = null;\n for (const operation of operations) {\n if (isSlotOperationConditionSatisfied(operation, activeRoles) && isLayoutReplaceOperation(operation)) {\n if (hasLayoutComponentProps(operation)) {\n layoutElement = operation.component;\n } else if (hasLayoutElementProps(operation)) {\n layoutElement = operation.element;\n }\n }\n }\n return layoutElement;\n }, [operations, activeRoles]);\n}\n\n/**\n * useLayoutOptions iterates through the slot's operations to find any which are \"layout\n * options\" operations. It merges these into a single object and returns them - operations are\n * merged in declaration order, meaning last one in wins.\n */\nexport function useLayoutOptions() {\n const { id } = useSlotContext();\n return useLayoutOptionsForId(id);\n}\n\nexport function useLayoutOptionsForId(id: string) {\n const operations = useSlotOperations(id);\n const activeRoles = useActiveRoles();\n\n return useMemo(() => {\n let options: Record<string, unknown> = {};\n for (const operation of operations) {\n if (isSlotOperationConditionSatisfied(operation, activeRoles) && isLayoutOptionsOperation(operation)) {\n options = { ...options, ...operation.options };\n }\n }\n return options;\n }, [operations, activeRoles]);\n}\n"]}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { SlotOperation } from './types';
|
|
2
2
|
export declare function getSlotOperations(ids: string[], defaultOperation?: SlotOperation): SlotOperation[];
|
|
3
|
-
export declare function isSlotOperationConditionSatisfied(operation: SlotOperation): boolean;
|
|
3
|
+
export declare function isSlotOperationConditionSatisfied(operation: SlotOperation, activeRoles: string[]): boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getAuthenticatedUser } from '../auth';
|
|
2
|
-
import {
|
|
2
|
+
import { getSiteConfig } from '../config';
|
|
3
3
|
export function getSlotOperations(ids, defaultOperation) {
|
|
4
4
|
const { apps } = getSiteConfig();
|
|
5
5
|
const ops = [];
|
|
@@ -19,7 +19,7 @@ export function getSlotOperations(ids, defaultOperation) {
|
|
|
19
19
|
}
|
|
20
20
|
return ops;
|
|
21
21
|
}
|
|
22
|
-
export function isSlotOperationConditionSatisfied(operation) {
|
|
22
|
+
export function isSlotOperationConditionSatisfied(operation, activeRoles) {
|
|
23
23
|
const { condition } = operation;
|
|
24
24
|
if ((condition === null || condition === void 0 ? void 0 : condition.authenticated) !== undefined) {
|
|
25
25
|
const isAuthenticated = getAuthenticatedUser() !== null;
|
|
@@ -29,7 +29,6 @@ export function isSlotOperationConditionSatisfied(operation) {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
if ((condition === null || condition === void 0 ? void 0 : condition.active) !== undefined || (condition === null || condition === void 0 ? void 0 : condition.inactive) !== undefined) {
|
|
32
|
-
const activeRoles = getActiveRoles();
|
|
33
32
|
if ((condition === null || condition === void 0 ? void 0 : condition.active) !== undefined) {
|
|
34
33
|
let activeConditionRoleFound = false;
|
|
35
34
|
for (const conditionRole of condition.active) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../runtime/slots/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAC/C,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../runtime/slots/utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { getAuthenticatedUser } from '../auth';\nimport { getSiteConfig } from '../config';\nimport { SlotOperation } from './types';\n\nexport function getSlotOperations(ids: string[], defaultOperation?: SlotOperation) {\n const { apps } = getSiteConfig();\n const ops: SlotOperation[] = [];\n\n if (defaultOperation) {\n ops.push(defaultOperation);\n }\n\n if (apps) {\n apps.forEach((app) => {\n if (Array.isArray(app.slots)) {\n app.slots.forEach((operation) => {\n if (ids.includes(operation.slotId)) {\n ops.push(operation);\n }\n });\n }\n });\n }\n\n return ops;\n}\n\nexport function isSlotOperationConditionSatisfied(operation: SlotOperation, activeRoles: string[]) {\n const { condition } = operation;\n if (condition?.authenticated !== undefined) {\n const isAuthenticated = getAuthenticatedUser() !== null;\n // If we failed the authenticated condition, return false.\n if (condition.authenticated !== isAuthenticated) {\n return false;\n }\n }\n\n if (condition?.active !== undefined || condition?.inactive !== undefined) {\n if (condition?.active !== undefined) {\n let activeConditionRoleFound = false;\n for (const conditionRole of condition.active) {\n if (activeRoles.includes(conditionRole)) {\n activeConditionRoleFound = true;\n break;\n }\n }\n\n // If we couldn't find an active role in our list, then we've failed this condition.\n if (!activeConditionRoleFound) {\n return false;\n }\n }\n\n if (condition?.inactive !== undefined) {\n let inactiveConditionRoleFound = false;\n for (const conditionRole of condition.inactive) {\n if (activeRoles.includes(conditionRole)) {\n inactiveConditionRoleFound = true;\n break;\n }\n }\n\n // If we find an active role from our inactive list, then we've failed this condition.\n if (inactiveConditionRoleFound) {\n return false;\n }\n }\n }\n\n if (condition?.callback !== undefined && condition.callback() === false) {\n return false;\n }\n\n // If there was no condition, we return true.\n return true;\n}\n"]}
|
|
@@ -6,8 +6,7 @@ export declare function useSortedWidgetOperations(id: string): WidgetOperation[]
|
|
|
6
6
|
/**
|
|
7
7
|
* useWidgetOptions iterates through the slot's operations to find any that are "widget options"
|
|
8
8
|
* operations specific to this widget. It merges these into a single object and returns them -
|
|
9
|
-
* operations are merged in declaration order, meaning last one in wins.
|
|
10
|
-
* triggers a re-render when the options change.
|
|
9
|
+
* operations are merged in declaration order, meaning last one in wins.
|
|
11
10
|
*/
|
|
12
11
|
export declare function useWidgetOptions(): Record<string, unknown>;
|
|
13
12
|
export declare function useWidgetOptionsForId(slotId: string, widgetId: string): Record<string, unknown>;
|
|
@@ -9,7 +9,8 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
9
9
|
}
|
|
10
10
|
return t;
|
|
11
11
|
};
|
|
12
|
-
import { useContext,
|
|
12
|
+
import { useContext, useMemo } from 'react';
|
|
13
|
+
import useActiveRoles from '../../react/hooks/useActiveRoles';
|
|
13
14
|
import { useSlotContext, useSlotOperations } from '../hooks';
|
|
14
15
|
import { isSlotOperationConditionSatisfied } from '../utils';
|
|
15
16
|
import { createWidgets, isWidgetAbsoluteOperation, isWidgetOperation, isWidgetOptionsOperation, isWidgetRelativeOperation } from './utils';
|
|
@@ -25,56 +26,44 @@ export function useWidgetsForId(id, componentProps) {
|
|
|
25
26
|
}
|
|
26
27
|
export function useWidgetOperations(id) {
|
|
27
28
|
const operations = useSlotOperations(id);
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
const filteredOperations = operations.filter((operation) => {
|
|
31
|
-
return isWidgetOperation(operation) && isSlotOperationConditionSatisfied(operation);
|
|
32
|
-
});
|
|
33
|
-
setWidgetOperations(filteredOperations);
|
|
34
|
-
}, [operations]);
|
|
35
|
-
return widgetOperations;
|
|
29
|
+
const activeRoles = useActiveRoles();
|
|
30
|
+
return useMemo(() => operations.filter((operation) => (isWidgetOperation(operation) && isSlotOperationConditionSatisfied(operation, activeRoles))), [operations, activeRoles]);
|
|
36
31
|
}
|
|
37
32
|
export function useSortedWidgetOperations(id) {
|
|
38
33
|
const operations = useWidgetOperations(id);
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
const
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
34
|
+
return useMemo(() => (
|
|
35
|
+
// This sorts widget operations in an order that guarantees that any 'related' widgets
|
|
36
|
+
// needed by relatively positioned operations (INSERT_AFTER, INSERT_BEFORE) should already exist
|
|
37
|
+
// by the time the relative operations are evaluated. It means the declaration order of
|
|
38
|
+
// operations in SiteConfig does not prevent an operation from interacting with a widget that was
|
|
39
|
+
// declared 'later'.
|
|
40
|
+
[...operations].sort((a, b) => {
|
|
41
|
+
const aAbsolute = isWidgetAbsoluteOperation(a);
|
|
42
|
+
const bAbsolute = isWidgetAbsoluteOperation(b);
|
|
43
|
+
if (aAbsolute && bAbsolute) {
|
|
44
|
+
return 0;
|
|
45
|
+
}
|
|
46
|
+
else if (aAbsolute) {
|
|
47
|
+
return -1;
|
|
48
|
+
}
|
|
49
|
+
else if (bAbsolute) {
|
|
50
|
+
return 1;
|
|
51
|
+
}
|
|
52
|
+
else if (isWidgetRelativeOperation(a) && isWidgetRelativeOperation(b)) {
|
|
53
|
+
if (a.id === b.relatedId) {
|
|
54
54
|
return -1;
|
|
55
55
|
}
|
|
56
|
-
else if (
|
|
56
|
+
else if (b.id === a.relatedId) {
|
|
57
57
|
return 1;
|
|
58
58
|
}
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
else if (b.id === a.relatedId) {
|
|
64
|
-
return 1;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return 0;
|
|
68
|
-
});
|
|
69
|
-
setSortedOperations(sortedOperations);
|
|
70
|
-
}, [operations]);
|
|
71
|
-
return sortedOperations;
|
|
59
|
+
}
|
|
60
|
+
return 0;
|
|
61
|
+
})), [operations]);
|
|
72
62
|
}
|
|
73
63
|
/**
|
|
74
64
|
* useWidgetOptions iterates through the slot's operations to find any that are "widget options"
|
|
75
65
|
* operations specific to this widget. It merges these into a single object and returns them -
|
|
76
|
-
* operations are merged in declaration order, meaning last one in wins.
|
|
77
|
-
* triggers a re-render when the options change.
|
|
66
|
+
* operations are merged in declaration order, meaning last one in wins.
|
|
78
67
|
*/
|
|
79
68
|
export function useWidgetOptions() {
|
|
80
69
|
const { slotId, widgetId } = useContext(WidgetContext);
|
|
@@ -82,23 +71,14 @@ export function useWidgetOptions() {
|
|
|
82
71
|
}
|
|
83
72
|
export function useWidgetOptionsForId(slotId, widgetId) {
|
|
84
73
|
const operations = useWidgetOperations(slotId);
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
if (isSlotOperationConditionSatisfied(operation)) {
|
|
91
|
-
if (isWidgetOptionsOperation(operation)) {
|
|
92
|
-
if (operation.relatedId === widgetId) {
|
|
93
|
-
nextOptions = Object.assign(Object.assign({}, nextOptions), operation.options);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
74
|
+
return useMemo(() => {
|
|
75
|
+
let options = {};
|
|
76
|
+
for (const operation of operations) {
|
|
77
|
+
if (isWidgetOptionsOperation(operation) && operation.relatedId === widgetId) {
|
|
78
|
+
options = Object.assign(Object.assign({}, options), operation.options);
|
|
97
79
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
setOptions(findOptions());
|
|
80
|
+
}
|
|
81
|
+
return options;
|
|
101
82
|
}, [widgetId, operations]);
|
|
102
|
-
return options;
|
|
103
83
|
}
|
|
104
84
|
//# sourceMappingURL=hooks.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/hooks.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,
|
|
1
|
+
{"version":3,"file":"hooks.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/hooks.ts"],"names":[],"mappings":";;;;;;;;;;;AAAA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,cAAc,MAAM,kCAAkC,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7D,OAAO,EAAE,iCAAiC,EAAE,MAAM,UAAU,CAAC;AAE7D,OAAO,EAAE,aAAa,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,SAAS,CAAC;AAC3I,OAAO,aAAa,MAAM,iBAAiB,CAAC;AAE5C,MAAM,UAAU,UAAU;IACxB,MAAM,KAAmB,cAAc,EAAE,EAAnC,EAAE,EAAE,OAA+B,EAA1B,KAAK,cAAd,MAAgB,CAAmB,CAAC;IAC1C,OAAO,KAAK,CAAC,QAAQ,CAAC;IACtB,OAAO,eAAe,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,EAAU,EAAE,cAAwC;IAClF,MAAM,UAAU,GAAG,yBAAyB,CAAC,EAAE,CAAC,CAAC;IACjD,OAAO,aAAa,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;AACnD,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,EAAU;IAC5C,MAAM,UAAU,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC;IACzC,MAAM,WAAW,GAAG,cAAc,EAAE,CAAC;IAErC,OAAO,OAAO,CACZ,GAAG,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,SAAS,EAAgC,EAAE,CAAC,CACnE,iBAAiB,CAAC,SAAS,CAAC,IAAI,iCAAiC,CAAC,SAAS,EAAE,WAAW,CAAC,CAC1F,CAAC,EACF,CAAC,UAAU,EAAE,WAAW,CAAC,CAC1B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,EAAU;IAClD,MAAM,UAAU,GAAG,mBAAmB,CAAC,EAAE,CAAC,CAAC;IAE3C,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC;IACnB,sFAAsF;IACtF,gGAAgG;IAChG,wFAAwF;IACxF,iGAAiG;IACjG,oBAAoB;IACpB,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAkB,EAAE,CAAkB,EAAE,EAAE;QAC9D,MAAM,SAAS,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,SAAS,GAAG,yBAAyB,CAAC,CAAC,CAAC,CAAC;QAC/C,IAAI,SAAS,IAAI,SAAS,EAAE,CAAC;YAC3B,OAAO,CAAC,CAAC;QACX,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC,CAAC;QACZ,CAAC;aAAM,IAAI,SAAS,EAAE,CAAC;YACrB,OAAO,CAAC,CAAC;QACX,CAAC;aAAM,IAAI,yBAAyB,CAAC,CAAC,CAAC,IAAI,yBAAyB,CAAC,CAAC,CAAC,EAAE,CAAC;YACxE,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;gBACzB,OAAO,CAAC,CAAC,CAAC;YACZ,CAAC;iBAAM,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,SAAS,EAAE,CAAC;gBAChC,OAAO,CAAC,CAAC;YACX,CAAC;QACH,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC,CAAC,CACH,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC,aAAa,CAAC,CAAC;IACvD,OAAO,qBAAqB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;AACjD,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,MAAc,EAAE,QAAgB;IACpE,MAAM,UAAU,GAAG,mBAAmB,CAAC,MAAM,CAAC,CAAC;IAE/C,OAAO,OAAO,CAAC,GAAG,EAAE;QAClB,IAAI,OAAO,GAA4B,EAAE,CAAC;QAC1C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,wBAAwB,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC5E,OAAO,mCAAQ,OAAO,GAAK,SAAS,CAAC,OAAO,CAAE,CAAC;YACjD,CAAC;QACH,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAC7B,CAAC","sourcesContent":["import { useContext, useMemo } from 'react';\nimport useActiveRoles from '../../react/hooks/useActiveRoles';\nimport { useSlotContext, useSlotOperations } from '../hooks';\nimport { isSlotOperationConditionSatisfied } from '../utils';\nimport { WidgetList, WidgetOperation } from './types';\nimport { createWidgets, isWidgetAbsoluteOperation, isWidgetOperation, isWidgetOptionsOperation, isWidgetRelativeOperation } from './utils';\nimport WidgetContext from './WidgetContext';\n\nexport function useWidgets(): WidgetList {\n const { id, ...props } = useSlotContext();\n delete props.children;\n return useWidgetsForId(id, props);\n}\n\nexport function useWidgetsForId(id: string, componentProps?: Record<string, unknown>): WidgetList {\n const operations = useSortedWidgetOperations(id);\n return createWidgets(operations, componentProps);\n}\n\nexport function useWidgetOperations(id: string) {\n const operations = useSlotOperations(id);\n const activeRoles = useActiveRoles();\n\n return useMemo(\n () => operations.filter((operation): operation is WidgetOperation => (\n isWidgetOperation(operation) && isSlotOperationConditionSatisfied(operation, activeRoles)\n )),\n [operations, activeRoles],\n );\n}\n\nexport function useSortedWidgetOperations(id: string) {\n const operations = useWidgetOperations(id);\n\n return useMemo(() => (\n // This sorts widget operations in an order that guarantees that any 'related' widgets\n // needed by relatively positioned operations (INSERT_AFTER, INSERT_BEFORE) should already exist\n // by the time the relative operations are evaluated. It means the declaration order of\n // operations in SiteConfig does not prevent an operation from interacting with a widget that was\n // declared 'later'.\n [...operations].sort((a: WidgetOperation, b: WidgetOperation) => {\n const aAbsolute = isWidgetAbsoluteOperation(a);\n const bAbsolute = isWidgetAbsoluteOperation(b);\n if (aAbsolute && bAbsolute) {\n return 0;\n } else if (aAbsolute) {\n return -1;\n } else if (bAbsolute) {\n return 1;\n } else if (isWidgetRelativeOperation(a) && isWidgetRelativeOperation(b)) {\n if (a.id === b.relatedId) {\n return -1;\n } else if (b.id === a.relatedId) {\n return 1;\n }\n }\n return 0;\n })\n ), [operations]);\n}\n\n/**\n * useWidgetOptions iterates through the slot's operations to find any that are \"widget options\"\n * operations specific to this widget. It merges these into a single object and returns them -\n * operations are merged in declaration order, meaning last one in wins.\n */\nexport function useWidgetOptions() {\n const { slotId, widgetId } = useContext(WidgetContext);\n return useWidgetOptionsForId(slotId, widgetId);\n}\n\nexport function useWidgetOptionsForId(slotId: string, widgetId: string) {\n const operations = useWidgetOperations(slotId);\n\n return useMemo(() => {\n let options: Record<string, unknown> = {};\n for (const operation of operations) {\n if (isWidgetOptionsOperation(operation) && operation.relatedId === widgetId) {\n options = { ...options, ...operation.options };\n }\n }\n return options;\n }, [widgetId, operations]);\n}\n"]}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
-
import { isSlotOperationConditionSatisfied } from '../utils';
|
|
3
2
|
import { IFrameWidget } from './iframe';
|
|
4
3
|
import { WidgetOperationTypes } from './types';
|
|
5
4
|
import WidgetProvider from './WidgetProvider';
|
|
@@ -158,25 +157,23 @@ function createWidgetList(identifiedWidgets) {
|
|
|
158
157
|
export function createWidgets(operations, componentProps) {
|
|
159
158
|
const identifiedWidgets = [];
|
|
160
159
|
for (const operation of operations) {
|
|
161
|
-
if (
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
removeWidget(operation, identifiedWidgets);
|
|
179
|
-
}
|
|
160
|
+
if (isWidgetAppendOperation(operation)) {
|
|
161
|
+
appendWidget(operation, identifiedWidgets, componentProps);
|
|
162
|
+
}
|
|
163
|
+
else if (isWidgetPrependOperation(operation)) {
|
|
164
|
+
prependWidget(operation, identifiedWidgets, componentProps);
|
|
165
|
+
}
|
|
166
|
+
else if (isWidgetInsertAfterOperation(operation)) {
|
|
167
|
+
insertAfterWidget(operation, identifiedWidgets, componentProps);
|
|
168
|
+
}
|
|
169
|
+
else if (isWidgetInsertBeforeOperation(operation)) {
|
|
170
|
+
insertBeforeWidget(operation, identifiedWidgets, componentProps);
|
|
171
|
+
}
|
|
172
|
+
else if (isWidgetReplaceOperation(operation)) {
|
|
173
|
+
replaceWidget(operation, identifiedWidgets, componentProps);
|
|
174
|
+
}
|
|
175
|
+
else if (isWidgetRemoveOperation(operation)) {
|
|
176
|
+
removeWidget(operation, identifiedWidgets);
|
|
180
177
|
}
|
|
181
178
|
}
|
|
182
179
|
return createWidgetList(identifiedWidgets);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/utils.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ReactNode } from 'react';\nimport { SlotOperation } from '../types';\nimport { isSlotOperationConditionSatisfied } from '../utils';\nimport { IFrameWidget } from './iframe';\nimport { IdentifiedWidget, WidgetAbsoluteOperation, WidgetAppendOperation, WidgetComponentProps, WidgetElementProps, WidgetIdentityProps, WidgetIFrameProps, WidgetInsertAfterOperation, WidgetInsertBeforeOperation, WidgetList, WidgetOperation, WidgetOperationTypes, WidgetOptionsOperation, WidgetPrependOperation, WidgetRemoveOperation, WidgetRendererOperation, WidgetRendererProps, WidgetReplaceOperation } from './types';\nimport WidgetProvider from './WidgetProvider';\n\nexport function isWidgetOperation(operation: SlotOperation): operation is WidgetOperation {\n return Object.values(WidgetOperationTypes).includes(operation.op as WidgetOperationTypes);\n}\n\nexport function isWidgetAbsoluteOperation(operation: WidgetOperation): operation is WidgetAbsoluteOperation {\n return operation.op === WidgetOperationTypes.APPEND || operation.op === WidgetOperationTypes.PREPEND;\n}\n\nexport function isWidgetRelativeOperation(operation: WidgetOperation): operation is (WidgetInsertAfterOperation | WidgetInsertBeforeOperation) {\n return operation.op === WidgetOperationTypes.INSERT_AFTER || operation.op === WidgetOperationTypes.INSERT_BEFORE;\n}\n\nexport function isWidgetAppendOperation(operation: SlotOperation): operation is WidgetAppendOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.APPEND;\n}\n\nexport function isWidgetInsertAfterOperation(operation: SlotOperation): operation is WidgetInsertAfterOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.INSERT_AFTER;\n}\n\nexport function isWidgetInsertBeforeOperation(operation: SlotOperation): operation is WidgetInsertBeforeOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.INSERT_BEFORE;\n}\n\nexport function isWidgetPrependOperation(operation: SlotOperation): operation is WidgetPrependOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.PREPEND;\n}\n\nexport function isWidgetRemoveOperation(operation: SlotOperation): operation is WidgetRemoveOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.REMOVE;\n}\n\nexport function isWidgetReplaceOperation(operation: SlotOperation): operation is WidgetReplaceOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.REPLACE;\n}\n\nexport function isWidgetOptionsOperation(operation: SlotOperation): operation is WidgetOptionsOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.OPTIONS;\n}\n\nexport function isWidgetRendererOperation(operation: SlotOperation): operation is WidgetRendererOperation {\n return isWidgetOperation(operation) && hasWidgetRendererProps(operation);\n}\n\nexport function isWidgetIdentityOperation(operation: SlotOperation): operation is (WidgetOperation & WidgetIdentityProps) {\n return isWidgetOperation(operation) && hasWidgetIdentityProps(operation);\n}\n\nexport function isWidgetIdentityRoleOperation(operation: SlotOperation): operation is (WidgetOperation & WidgetIdentityProps & { role: string }) {\n return isWidgetIdentityOperation(operation) && hasWidgetIdentityRoleProps(operation);\n}\n\nexport function createWidgetAppendOperation(id: string, slotId: string, element: ReactNode) {\n let operation: WidgetOperation | undefined = undefined;\n if (element) {\n operation = {\n slotId,\n id,\n op: WidgetOperationTypes.APPEND,\n element\n };\n }\n\n return operation;\n}\n\n// Widget Operation props helpers\n\nfunction hasWidgetComponentProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetComponentProps) {\n return isWidgetOperation(operation) && 'component' in operation;\n}\n\nfunction hasWidgetElementProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetElementProps) {\n return isWidgetOperation(operation) && 'element' in operation;\n}\n\nfunction hasWidgetIFrameProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetIFrameProps) {\n return isWidgetOperation(operation) && 'url' in operation && 'title' in operation;\n}\n\nfunction hasWidgetRendererProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetRendererProps) {\n return hasWidgetComponentProps(operation) || hasWidgetElementProps(operation) || hasWidgetIFrameProps(operation);\n}\n\nfunction hasWidgetIdentityProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetIdentityProps) {\n return isWidgetOperation(operation) && 'id' in operation;\n}\n\nfunction hasWidgetIdentityRoleProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetIdentityProps & { role: string }) {\n return hasWidgetIdentityProps(operation) && 'role' in operation;\n}\n\n/**\n * An 'identified' widget just means a data structure with an ID and a ReactNode.\n */\nfunction createIdentifiedWidget(operation: WidgetRendererOperation, componentProps?: Record<string, unknown>) {\n let widget: ReactNode = null;\n const { id } = operation;\n if (hasWidgetComponentProps(operation)) {\n widget = (\n <operation.component {...componentProps} />\n );\n } else if (hasWidgetElementProps(operation)) {\n widget = operation.element;\n } else if (hasWidgetIFrameProps(operation)) {\n widget = (\n <IFrameWidget url={operation.url} title={operation.title} />\n );\n }\n\n return {\n id,\n role: operation.role,\n node: (\n <WidgetProvider key={id} slotId={operation.slotId} widgetId={operation.id} role={operation.role}>\n {widget}\n </WidgetProvider>\n ),\n };\n}\n\nfunction findRelatedWidgetIndex(id: string, widgets: IdentifiedWidget[]) {\n for (const candidateRelatedWidget of widgets) {\n if (candidateRelatedWidget.id === id) {\n return widgets.indexOf(candidateRelatedWidget);\n }\n }\n return null;\n}\n\nfunction appendWidget(operation: WidgetAppendOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n widgets.push(widget);\n}\n\nfunction prependWidget(operation: WidgetPrependOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n widgets.unshift(widget);\n}\n\nfunction insertAfterWidget(operation: WidgetInsertAfterOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex + 1, 0, widget);\n }\n}\n\nfunction insertBeforeWidget(operation: WidgetInsertBeforeOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex, 0, widget);\n }\n}\n\nfunction replaceWidget(operation: WidgetReplaceOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex, 1, widget);\n }\n}\n\nfunction removeWidget(operation: WidgetRemoveOperation, widgets: IdentifiedWidget[]) {\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex, 1);\n }\n}\n\nfunction createWidgetList(identifiedWidgets: IdentifiedWidget[]): WidgetList {\n const nodes = identifiedWidgets.map(widget => widget.node);\n const widgetList = nodes as WidgetList;\n\n widgetList.identified = identifiedWidgets;\n\n widgetList.byId = (id: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.id === id).map(w => w.node);\n };\n\n widgetList.withoutId = (id: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.id !== id).map(w => w.node);\n };\n\n widgetList.byRole = (role: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.role === role).map(w => w.node);\n };\n\n widgetList.withoutRole = (role: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.role !== role).map(w => w.node);\n };\n\n return widgetList;\n}\n\nexport function createWidgets(operations: WidgetOperation[], componentProps?: Record<string, unknown>): WidgetList {\n const identifiedWidgets: IdentifiedWidget[] = [];\n\n for (const operation of operations) {\n if (isSlotOperationConditionSatisfied(operation)) {\n if (isWidgetAppendOperation(operation)) {\n appendWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetPrependOperation(operation)) {\n prependWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetInsertAfterOperation(operation)) {\n insertAfterWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetInsertBeforeOperation(operation)) {\n insertBeforeWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetReplaceOperation(operation)) {\n replaceWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetRemoveOperation(operation)) {\n removeWidget(operation, identifiedWidgets);\n }\n }\n }\n\n return createWidgetList(identifiedWidgets);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../../runtime/slots/widget/utils.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ReactNode } from 'react';\nimport { SlotOperation } from '../types';\nimport { IFrameWidget } from './iframe';\nimport { IdentifiedWidget, WidgetAbsoluteOperation, WidgetAppendOperation, WidgetComponentProps, WidgetElementProps, WidgetIdentityProps, WidgetIFrameProps, WidgetInsertAfterOperation, WidgetInsertBeforeOperation, WidgetList, WidgetOperation, WidgetOperationTypes, WidgetOptionsOperation, WidgetPrependOperation, WidgetRemoveOperation, WidgetRendererOperation, WidgetRendererProps, WidgetReplaceOperation } from './types';\nimport WidgetProvider from './WidgetProvider';\n\nexport function isWidgetOperation(operation: SlotOperation): operation is WidgetOperation {\n return Object.values(WidgetOperationTypes).includes(operation.op as WidgetOperationTypes);\n}\n\nexport function isWidgetAbsoluteOperation(operation: WidgetOperation): operation is WidgetAbsoluteOperation {\n return operation.op === WidgetOperationTypes.APPEND || operation.op === WidgetOperationTypes.PREPEND;\n}\n\nexport function isWidgetRelativeOperation(operation: WidgetOperation): operation is (WidgetInsertAfterOperation | WidgetInsertBeforeOperation) {\n return operation.op === WidgetOperationTypes.INSERT_AFTER || operation.op === WidgetOperationTypes.INSERT_BEFORE;\n}\n\nexport function isWidgetAppendOperation(operation: SlotOperation): operation is WidgetAppendOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.APPEND;\n}\n\nexport function isWidgetInsertAfterOperation(operation: SlotOperation): operation is WidgetInsertAfterOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.INSERT_AFTER;\n}\n\nexport function isWidgetInsertBeforeOperation(operation: SlotOperation): operation is WidgetInsertBeforeOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.INSERT_BEFORE;\n}\n\nexport function isWidgetPrependOperation(operation: SlotOperation): operation is WidgetPrependOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.PREPEND;\n}\n\nexport function isWidgetRemoveOperation(operation: SlotOperation): operation is WidgetRemoveOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.REMOVE;\n}\n\nexport function isWidgetReplaceOperation(operation: SlotOperation): operation is WidgetReplaceOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.REPLACE;\n}\n\nexport function isWidgetOptionsOperation(operation: SlotOperation): operation is WidgetOptionsOperation {\n return isWidgetOperation(operation) && operation.op === WidgetOperationTypes.OPTIONS;\n}\n\nexport function isWidgetRendererOperation(operation: SlotOperation): operation is WidgetRendererOperation {\n return isWidgetOperation(operation) && hasWidgetRendererProps(operation);\n}\n\nexport function isWidgetIdentityOperation(operation: SlotOperation): operation is (WidgetOperation & WidgetIdentityProps) {\n return isWidgetOperation(operation) && hasWidgetIdentityProps(operation);\n}\n\nexport function isWidgetIdentityRoleOperation(operation: SlotOperation): operation is (WidgetOperation & WidgetIdentityProps & { role: string }) {\n return isWidgetIdentityOperation(operation) && hasWidgetIdentityRoleProps(operation);\n}\n\nexport function createWidgetAppendOperation(id: string, slotId: string, element: ReactNode) {\n let operation: WidgetOperation | undefined = undefined;\n if (element) {\n operation = {\n slotId,\n id,\n op: WidgetOperationTypes.APPEND,\n element\n };\n }\n\n return operation;\n}\n\n// Widget Operation props helpers\n\nfunction hasWidgetComponentProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetComponentProps) {\n return isWidgetOperation(operation) && 'component' in operation;\n}\n\nfunction hasWidgetElementProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetElementProps) {\n return isWidgetOperation(operation) && 'element' in operation;\n}\n\nfunction hasWidgetIFrameProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetIFrameProps) {\n return isWidgetOperation(operation) && 'url' in operation && 'title' in operation;\n}\n\nfunction hasWidgetRendererProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetRendererProps) {\n return hasWidgetComponentProps(operation) || hasWidgetElementProps(operation) || hasWidgetIFrameProps(operation);\n}\n\nfunction hasWidgetIdentityProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetIdentityProps) {\n return isWidgetOperation(operation) && 'id' in operation;\n}\n\nfunction hasWidgetIdentityRoleProps(operation: WidgetOperation): operation is (WidgetOperation & WidgetIdentityProps & { role: string }) {\n return hasWidgetIdentityProps(operation) && 'role' in operation;\n}\n\n/**\n * An 'identified' widget just means a data structure with an ID and a ReactNode.\n */\nfunction createIdentifiedWidget(operation: WidgetRendererOperation, componentProps?: Record<string, unknown>) {\n let widget: ReactNode = null;\n const { id } = operation;\n if (hasWidgetComponentProps(operation)) {\n widget = (\n <operation.component {...componentProps} />\n );\n } else if (hasWidgetElementProps(operation)) {\n widget = operation.element;\n } else if (hasWidgetIFrameProps(operation)) {\n widget = (\n <IFrameWidget url={operation.url} title={operation.title} />\n );\n }\n\n return {\n id,\n role: operation.role,\n node: (\n <WidgetProvider key={id} slotId={operation.slotId} widgetId={operation.id} role={operation.role}>\n {widget}\n </WidgetProvider>\n ),\n };\n}\n\nfunction findRelatedWidgetIndex(id: string, widgets: IdentifiedWidget[]) {\n for (const candidateRelatedWidget of widgets) {\n if (candidateRelatedWidget.id === id) {\n return widgets.indexOf(candidateRelatedWidget);\n }\n }\n return null;\n}\n\nfunction appendWidget(operation: WidgetAppendOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n widgets.push(widget);\n}\n\nfunction prependWidget(operation: WidgetPrependOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n widgets.unshift(widget);\n}\n\nfunction insertAfterWidget(operation: WidgetInsertAfterOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex + 1, 0, widget);\n }\n}\n\nfunction insertBeforeWidget(operation: WidgetInsertBeforeOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex, 0, widget);\n }\n}\n\nfunction replaceWidget(operation: WidgetReplaceOperation, widgets: IdentifiedWidget[], componentProps?: Record<string, unknown>) {\n const widget = createIdentifiedWidget(operation, componentProps);\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex, 1, widget);\n }\n}\n\nfunction removeWidget(operation: WidgetRemoveOperation, widgets: IdentifiedWidget[]) {\n const relatedIndex = findRelatedWidgetIndex(operation.relatedId, widgets);\n if (relatedIndex !== null) {\n widgets.splice(relatedIndex, 1);\n }\n}\n\nfunction createWidgetList(identifiedWidgets: IdentifiedWidget[]): WidgetList {\n const nodes = identifiedWidgets.map(widget => widget.node);\n const widgetList = nodes as WidgetList;\n\n widgetList.identified = identifiedWidgets;\n\n widgetList.byId = (id: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.id === id).map(w => w.node);\n };\n\n widgetList.withoutId = (id: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.id !== id).map(w => w.node);\n };\n\n widgetList.byRole = (role: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.role === role).map(w => w.node);\n };\n\n widgetList.withoutRole = (role: string): ReactNode[] => {\n return identifiedWidgets.filter(w => w.role !== role).map(w => w.node);\n };\n\n return widgetList;\n}\n\nexport function createWidgets(operations: WidgetOperation[], componentProps?: Record<string, unknown>): WidgetList {\n const identifiedWidgets: IdentifiedWidget[] = [];\n\n for (const operation of operations) {\n if (isWidgetAppendOperation(operation)) {\n appendWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetPrependOperation(operation)) {\n prependWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetInsertAfterOperation(operation)) {\n insertAfterWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetInsertBeforeOperation(operation)) {\n insertBeforeWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetReplaceOperation(operation)) {\n replaceWidget(operation, identifiedWidgets, componentProps);\n } else if (isWidgetRemoveOperation(operation)) {\n removeWidget(operation, identifiedWidgets);\n }\n }\n\n return createWidgetList(identifiedWidgets);\n}\n"]}
|
package/dist/runtime/utils.js
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
*
|
|
4
4
|
* @module Utilities
|
|
5
5
|
*/
|
|
6
|
-
import camelCase from 'lodash
|
|
7
|
-
import snakeCase from 'lodash
|
|
6
|
+
import camelCase from 'lodash/camelCase';
|
|
7
|
+
import snakeCase from 'lodash/snakeCase';
|
|
8
8
|
/**
|
|
9
9
|
* This is the underlying function used by camelCaseObject, snakeCaseObject, and convertKeyNames
|
|
10
10
|
* above.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../runtime/utils.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,SAAS,MAAM,kBAAkB,CAAC;AACzC,OAAO,SAAS,MAAM,kBAAkB,CAAC;AAEzC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAM,EAAE,MAAM;IAC7C,uDAAuD;IACvD,IACE,MAAM,KAAK,SAAS;WACjB,MAAM,KAAK,IAAI;WACf,CAAC,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EACzD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1B,OAAO,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED,mCAAmC;IACnC,MAAM,MAAM,GAAG,EAAE,CAAC;IAClB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;QAC9C,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,GAAG,gBAAgB,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACxD,CAAC,CAAC,CAAC;IACH,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,MAAM;IACpC,OAAO,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe,CAAC,MAAM;IACpC,OAAO,gBAAgB,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,UAAU,eAAe,CAAC,MAAM,EAAE,OAAO;IAC7C,MAAM,WAAW,GAAG,GAAG,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;IAE7E,OAAO,gBAAgB,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;AAC/C,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,MAAM;IAChE,MAAM,iBAAiB,GAAG,MAAM;SAC7B,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;SAC9B,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IAE/B,OAAO,iBAAiB,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,gBAAgB,EAAE,EAAE;QAC3D,MAAM,KAAK,GAAG,gBAAgB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5C,MAAM,GAAG,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;QAC7C,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QAChD,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACrE,CAAC,EAAE,EAAE,CAAC,CAAC;AACT,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,IAAI;IACtC,8CAA8C;IAC9C,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,EAAE,EAAE,CAAC;QAC5C,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uEAAuE;IACvE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,iFAAiF;IACjF,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,0CAA0C;IAC1C,MAAM,gBAAgB,GAAG;QACvB,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU;QACtD,UAAU,EAAE,SAAS,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM;QACrD,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU;QAC1D,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ;QAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK;QACjD,QAAQ,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO;KAClD,CAAC;IACF,IAAI,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC","sourcesContent":["/**\n * #### Import members from **@openedx/frontend-base**\n *\n * @module Utilities\n */\nimport camelCase from 'lodash
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../runtime/utils.js"],"names":[],"mappings":"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","sourcesContent":["/**\n * #### Import members from **@openedx/frontend-base**\n *\n * @module Utilities\n */\nimport camelCase from 'lodash/camelCase';\nimport snakeCase from 'lodash/snakeCase';\n\n/**\n * This is the underlying function used by camelCaseObject, snakeCaseObject, and convertKeyNames\n * above.\n *\n * Given an object (or array) and a modification function, will perform the function on each key it\n * encounters on the object and its tree of children.\n *\n * The modification function must take a string as an argument and returns a string.\n *\n * Example:\n *\n * ```\n * (key) => {\n * if (key === 'edX') {\n * return 'Open edX';\n * }\n * return key;\n * }\n * ```\n *\n * This function will turn any key that matches 'edX' into 'Open edX'. All other keys will be\n * passed through unmodified.\n *\n * Can accept arrays as well as objects, and will perform its conversion on any objects it finds in\n * the array.\n *\n * @param {Object} object\n * @param {function} modify\n * @returns {Object}\n */\nexport function modifyObjectKeys(object, modify) {\n // If the passed in object is not an Object, return it.\n if (\n object === undefined\n || object === null\n || (typeof object !== 'object' && !Array.isArray(object))\n ) {\n return object;\n }\n\n if (Array.isArray(object)) {\n return object.map(value => modifyObjectKeys(value, modify));\n }\n\n // Otherwise, process all its keys.\n const result = {};\n Object.entries(object).forEach(([key, value]) => {\n result[modify(key)] = modifyObjectKeys(value, modify);\n });\n return result;\n}\n\n/**\n * Performs a deep conversion to camelCase on all keys in the provided object and its tree of\n * children. Uses [lodash.camelcase](https://lodash.com/docs/4.17.15#camelCase) on each key. This\n * is commonly used to convert snake_case keys in models from a backend server into camelCase keys\n * for use in the JavaScript client.\n *\n * Can accept arrays as well as objects, and will perform its conversion on any objects it finds in\n * the array.\n *\n * @param {Array|Object} object\n * @returns {Array|Object}\n */\nexport function camelCaseObject(object) {\n return modifyObjectKeys(object, camelCase);\n}\n\n/**\n * Performs a deep conversion to snake_case on all keys in the provided object and its tree of\n * children. Uses [lodash.snakecase](https://lodash.com/docs/4.17.15#snakeCase) on each key. This\n * is commonly used to convert camelCase keys from the JavaScript app into snake_case keys expected\n * by backend servers.\n *\n * Can accept arrays as well as objects, and will perform its conversion on any objects it finds in\n * the array.\n *\n * @param {Array|Object} object\n * @returns {Array|Object}\n */\nexport function snakeCaseObject(object) {\n return modifyObjectKeys(object, snakeCase);\n}\n\n/**\n * Given a map of key-value pairs, performs a deep conversion key names in the specified object\n * _from_ the key _to_ the value. This is useful for updating names in an API request to the names\n * used throughout a client application if they happen to differ. It can also be used in the\n * reverse - formatting names from the client application to names expected by an API.\n *\n * ```\n * import { convertKeyNames } from '@openedx/frontend-base';\n *\n * // This object can be of any shape or depth with subobjects/arrays.\n * const myObject = {\n * myKey: 'my value',\n * }\n *\n * const result = convertKeyNames(myObject, { myKey: 'their_key' });\n *\n * console.log(result) // { their_key: 'my value' }\n * ```\n *\n * Can accept arrays as well as objects, and will perform its conversion on any objects it finds in\n * the array.\n *\n * @param {Array|Object} object\n * @param {Object} nameMap\n * @returns {Array|Object}\n */\nexport function convertKeyNames(object, nameMap) {\n const transformer = key => (nameMap[key] === undefined ? key : nameMap[key]);\n\n return modifyObjectKeys(object, transformer);\n}\n\n/**\n * *Deprecated*: A method which converts the supplied query string into an object of\n * key-value pairs and returns it. Defaults to the current query string - should perform like\n * [window.searchParams](https://developer.mozilla.org/en-US/docs/Web/API/URL/searchParams)\n *\n * @deprecated\n * @param {string} [search=global.location.search]\n * @returns {Object}\n */\nexport function getQueryParameters(search = global.location.search) {\n const keyValueFragments = search\n .slice(search.indexOf('?') + 1)\n .split('&')\n .filter(hash => hash !== '');\n\n return keyValueFragments.reduce((params, keyValueFragment) => {\n const split = keyValueFragment.indexOf('=');\n const key = keyValueFragment.slice(0, split);\n const value = keyValueFragment.slice(split + 1);\n return Object.assign(params, { [key]: decodeURIComponent(value) });\n }, {});\n}\n\nexport function isValidVariableName(name) {\n // Check if the name is a string and not empty\n if (typeof name !== 'string' || name === '') {\n return false;\n }\n\n // Check if the first character is a letter, underscore, or dollar sign\n if (!/^[a-zA-Z_$]/.test(name)) {\n return false;\n }\n\n // Check if the name contains only letters, numbers, underscores, or dollar signs\n if (!/^[a-zA-Z0-9_$]+$/.test(name)) {\n return false;\n }\n\n // Check if the name is a reserved keyword\n const reservedKeywords = [\n 'break', 'case', 'catch', 'class', 'const', 'continue',\n 'debugger', 'default', 'delete', 'do', 'else', 'enum',\n 'export', 'extends', 'false', 'finally', 'for', 'function',\n 'if', 'import', 'in', 'instanceof', 'new', 'null', 'return',\n 'super', 'switch', 'this', 'throw', 'true', 'try',\n 'typeof', 'var', 'void', 'while', 'with', 'yield'\n ];\n if (reservedKeywords.includes(name)) {\n return false;\n }\n\n return true;\n}\n"]}
|
|
@@ -7,12 +7,12 @@ exports.prepareAllPackageMessages = prepareAllPackageMessages;
|
|
|
7
7
|
exports.prepareSiteMessages = prepareSiteMessages;
|
|
8
8
|
exports.prepare = prepare;
|
|
9
9
|
const fs_1 = __importDefault(require("fs"));
|
|
10
|
-
const
|
|
10
|
+
const camelCase_1 = __importDefault(require("lodash/camelCase"));
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const messagesObject_1 = require("./messagesObject");
|
|
13
13
|
function packageVarName(packagePath) {
|
|
14
14
|
const name = packagePath.split('/').pop();
|
|
15
|
-
return `${(0,
|
|
15
|
+
return `${(0, camelCase_1.default)(name)}Messages`;
|
|
16
16
|
}
|
|
17
17
|
function getPackageMessages(messagesDir, packagePath) {
|
|
18
18
|
return (0, messagesObject_1.generateMessagesObject)(path_1.default.join(messagesDir, packagePath));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openedx/frontend-base",
|
|
3
|
-
"version": "1.0.0-alpha.
|
|
3
|
+
"version": "1.0.0-alpha.41",
|
|
4
4
|
"description": "Build tools, setup and config for frontend apps",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -73,7 +73,6 @@
|
|
|
73
73
|
"@tanstack/react-query-devtools": "^5.99.0",
|
|
74
74
|
"@types/eslint__js": "^8.42.3",
|
|
75
75
|
"@types/gradient-string": "^1.1.6",
|
|
76
|
-
"@types/lodash.keyby": "^4.6.9",
|
|
77
76
|
"autoprefixer": "^10.4.20",
|
|
78
77
|
"axios": "^1.7.9",
|
|
79
78
|
"axios-cache-interceptor": "^1.6.0",
|
|
@@ -107,11 +106,7 @@
|
|
|
107
106
|
"jwt-decode": "^3.1.2",
|
|
108
107
|
"localforage": "^1.10.0",
|
|
109
108
|
"localforage-memoryStorageDriver": "^0.9.2",
|
|
110
|
-
"lodash
|
|
111
|
-
"lodash.keyby": "^4.6.0",
|
|
112
|
-
"lodash.memoize": "^4.1.2",
|
|
113
|
-
"lodash.merge": "^4.6.2",
|
|
114
|
-
"lodash.snakecase": "^4.1.1",
|
|
109
|
+
"lodash": "^4.18.1",
|
|
115
110
|
"mini-css-extract-plugin": "1.6.2",
|
|
116
111
|
"parse5": "7.3.0",
|
|
117
112
|
"postcss": "^8.4.47",
|
|
@@ -155,8 +150,7 @@
|
|
|
155
150
|
"@tsconfig/node24": "^24.0.4",
|
|
156
151
|
"@types/compression": "^1.7.5",
|
|
157
152
|
"@types/jest": "^29.5.14",
|
|
158
|
-
"@types/lodash
|
|
159
|
-
"@types/lodash.merge": "^4.6.9",
|
|
153
|
+
"@types/lodash": "^4.17.24",
|
|
160
154
|
"@types/node": "^24.12.0",
|
|
161
155
|
"@types/react": "^18.3.20",
|
|
162
156
|
"@types/react-dom": "^18.3.6",
|