@edx/frontend-platform 1.12.6 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -77,6 +77,21 @@ initialize({
77
77
  });
78
78
  ```
79
79
 
80
+ When using runtime configuration via `mergeConfig` noted above, `getConfig` must be called within a component's render lifecycle in order for the added keys and values to be returned in the configuration object. If `getConfig` is called outside of a component's render lifecycle, the custom configuration key/value pairs will not initially be part of the object returned by `getConfig`. For example:
81
+
82
+ ```jsx
83
+ import { getConfig } from '@edx/frontend-platform/config';
84
+
85
+ // The runtime configuration `CUSTOM_VARIABLE` added in the above code snippet will not appear here. This is
86
+ // because `getConfig` is called before `mergeConfig` is executed to add the custom runtime configuration.
87
+ console.log(getConfig().CUSTOM_VARIABLE); // returns undefined
88
+
89
+ const ExampleComponent = () => {
90
+ // This returns the value as expected since it is called after `mergeConfig` has already executed.
91
+ console.log(getConfig().CUSTOM_VARIABLE)
92
+ };
93
+ ```
94
+
80
95
  ### Service interfaces
81
96
 
82
97
  Each service (analytics, auth, i18n, logging) provided by frontend-platform has a API contract which all implementations of that service are guaranteed to fulfill. Applications that use frontend-platform can use its configured services via a convenient set of exported functions. An application that wants to use the service interfaces need only initialize them via the initialize() function, optionally providing custom service interfaces as desired (you probably won't need to).
@@ -89,6 +89,13 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
89
89
  // Create an async script element based on your key.
90
90
  var script = document.createElement('script');
91
91
  script.type = 'text/javascript';
92
+
93
+ script.onerror = function () {
94
+ _this.segmentInitialized = false;
95
+ var event = new Event('segmentFailed');
96
+ document.dispatchEvent(event);
97
+ };
98
+
92
99
  script.async = true;
93
100
  script.src = "https://cdn.segment.com/analytics.js/v1/".concat(key, "/analytics.min.js"); // Insert our script next to the first script element.
94
101
 
@@ -199,13 +206,18 @@ var SegmentAnalyticsService = /*#__PURE__*/function () {
199
206
  global.analytics.identify(traits);
200
207
  _this3.hasIdentifyBeenCalled = true;
201
208
  resolve();
202
- }); // if the segment domain is blocked on user's network/browser, this promise does not get
203
- // resolved and user see a blank page, set timeout out to resolve the promise.
209
+ }); // this is added to handle a specific use-case where if a user has blocked the analytics
210
+ // tools in their browser, this promise does not get resolved and user sees a blank
211
+ // page. Dispatching this event in script.onerror callback in analytics.load.
212
+
213
+ document.addEventListener('segmentFailed', resolve); // This is added to handle the google analytics blocked case which is injected into
214
+ // the DOM by segment.min.js.
204
215
 
205
216
  setTimeout(function () {
206
- // Other segment calls won't work if we are not identified. So let's just un-initialize ourselves.
207
- _this3.segmentInitialized = false;
208
- resolve();
217
+ if (!global.ga || !global.ga.create) {
218
+ _this3.segmentInitialized = false;
219
+ resolve();
220
+ }
209
221
  }, 2000);
210
222
  });
211
223
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/analytics/SegmentAnalyticsService.js"],"names":["formurlencoded","snakeCaseObject","SegmentAnalyticsService","httpClient","loggingService","config","trackingLogApiUrl","LMS_BASE_URL","segmentKey","SEGMENT_KEY","hasIdentifyBeenCalled","segmentInitialized","initializeSegment","global","analytics","initialize","invoked","methods","factory","method","args","unshift","push","forEach","key","load","options","script","document","createElement","type","async","src","first","getElementsByTagName","parentNode","insertBefore","_loadOptions","SNIPPET_VERSION","logError","eventName","properties","snakeEventData","deep","serverData","event_type","event","JSON","stringify","page","location","href","post","headers","error","userId","traits","Error","identify","Promise","resolve","reject","ready","user","id","reset","setTimeout","checkIdentifyCalled","track","category","name"],"mappings":"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","sourcesContent":["import formurlencoded from 'form-urlencoded';\nimport { snakeCaseObject } from '../utils';\n\n/**\n * @implements {AnalyticsService}\n * @memberof module:Analytics\n */\nclass SegmentAnalyticsService {\n constructor({ httpClient, loggingService, config }) {\n this.loggingService = loggingService;\n this.httpClient = httpClient;\n this.trackingLogApiUrl = `${config.LMS_BASE_URL}/event`;\n this.segmentKey = config.SEGMENT_KEY;\n this.hasIdentifyBeenCalled = false;\n this.segmentInitialized = false;\n\n if (this.segmentKey) {\n this.initializeSegment();\n }\n }\n\n // The code in this function is from Segment's website, with a few updates:\n // - It uses the segmentKey from the SegmentAnalyticsService instance.\n // - It also saves a \"segmentInitialized\" variable on the SegmentAnalyticsService instance so\n // that the service can keep track of its own initialization state.\n // Reference:\n // https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/\n initializeSegment() {\n // Create a queue, but don't obliterate an existing one!\n global.analytics = global.analytics || [];\n const { analytics } = global;\n\n // If the real analytics.js is already on the page return.\n if (analytics.initialize) {\n this.segmentInitialized = true;\n return;\n }\n\n // If the snippet was invoked do nothing.\n if (analytics.invoked) {\n this.segmentInitialized = true;\n return;\n }\n\n // Invoked flag, to make sure the snippet\n // is never invoked twice.\n analytics.invoked = true;\n\n // A list of the methods in Analytics.js to stub.\n analytics.methods = [\n 'trackSubmit',\n 'trackClick',\n 'trackLink',\n 'trackForm',\n 'pageview',\n 'identify',\n 'reset',\n 'group',\n 'track',\n 'ready',\n 'alias',\n 'debug',\n 'page',\n 'once',\n 'off',\n 'on',\n ];\n\n // Define a factory to create stubs. These are placeholders\n // for methods in Analytics.js so that you never have to wait\n // for it to load to actually record data. The `method` is\n // stored as the first argument, so we can replay the data.\n analytics.factory = method => ((...args) => {\n args.unshift(method);\n analytics.push(args);\n return analytics;\n });\n\n // For each of our methods, generate a queueing stub.\n analytics.methods.forEach((key) => {\n analytics[key] = analytics.factory(key);\n });\n\n // Define a method to load Analytics.js from our CDN,\n // and that will be sure to only ever load it once.\n analytics.load = (key, options) => {\n // Create an async script element based on your key.\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.async = true;\n script.src = `https://cdn.segment.com/analytics.js/v1/${key}/analytics.min.js`;\n\n // Insert our script next to the first script element.\n const first = document.getElementsByTagName('script')[0];\n first.parentNode.insertBefore(script, first);\n analytics._loadOptions = options; // eslint-disable-line no-underscore-dangle\n\n this.segmentInitialized = true;\n };\n\n // Add a version to keep track of what's in the wild.\n analytics.SNIPPET_VERSION = '4.1.0';\n\n // Load Analytics.js with your key, which will automatically\n // load the tools you've enabled for your account. Boosh!\n analytics.load(this.segmentKey);\n }\n\n /**\n * Checks that identify was first called. Otherwise, logs error.\n *\n */\n checkIdentifyCalled() {\n if (!this.hasIdentifyBeenCalled) {\n this.loggingService.logError('Identify must be called before other tracking events.');\n }\n }\n\n /**\n * Logs events to tracking log and downstream.\n * For tracking log event documentation, see\n * https://openedx.atlassian.net/wiki/spaces/AN/pages/13205895/Event+Design+and+Review+Process\n *\n * @param {string} eventName (event_type on backend, but named to match Segment api)\n * @param {Object} properties (event on backend, but named properties to match Segment api)\n * @returns {Promise} The promise returned by HttpClient.post.\n */\n sendTrackingLogEvent(eventName, properties) {\n const snakeEventData = snakeCaseObject(properties, { deep: true });\n const serverData = {\n event_type: eventName,\n event: JSON.stringify(snakeEventData),\n page: global.location.href,\n };\n return this.httpClient.post(\n this.trackingLogApiUrl,\n formurlencoded(serverData),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n },\n ).catch((error) => {\n this.loggingService.logError(error);\n });\n }\n\n /**\n * * Send identify call to Segment.\n *\n * @param {string} userId\n * @param {*} [traits]\n */\n identifyAuthenticatedUser(userId, traits) {\n if (!userId) {\n throw new Error('UserId is required for identifyAuthenticatedUser.');\n }\n\n if (!this.segmentInitialized) {\n return;\n }\n global.analytics.identify(userId, traits);\n this.hasIdentifyBeenCalled = true;\n }\n\n /**\n * Send anonymous identify call to Segment's identify.\n *\n * @param {*} [traits]\n * @returns {Promise} Promise that will resolve once the document readyState is complete\n */\n identifyAnonymousUser(traits) {\n if (!this.segmentInitialized) {\n return Promise.resolve();\n }\n // if we do not have an authenticated user (indicated by being in this method),\n // but we still have a user id associated in segment, reset the local segment state\n // This has to be wrapped in the analytics.ready() callback because the analytics.user()\n // function isn't available until the analytics.js package has finished initializing.\n return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars\n global.analytics.ready(() => {\n if (global.analytics.user().id()) {\n global.analytics.reset();\n }\n global.analytics.identify(traits);\n this.hasIdentifyBeenCalled = true;\n resolve();\n });\n\n // if the segment domain is blocked on user's network/browser, this promise does not get\n // resolved and user see a blank page, set timeout out to resolve the promise.\n setTimeout(() => {\n // Other segment calls won't work if we are not identified. So let's just un-initialize ourselves.\n this.segmentInitialized = false;\n resolve();\n }, 2000);\n });\n }\n\n /**\n * Sends a track event to Segment and downstream.\n * Note: For links and forms, you should use trackLink and trackForm instead.\n *\n * @param {*} eventName\n * @param {*} [properties]\n */\n sendTrackEvent(eventName, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.track(eventName, properties);\n }\n\n /**\n * Sends a page event to Segment and downstream.\n *\n * @param {*} [name] If only one string arg provided, assumed to be name.\n * @param {*} [category] Name is required to pass a category.\n * @param {*} [properties]\n */\n sendPageEvent(category, name, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.page(category, name, properties);\n }\n}\n\nexport default SegmentAnalyticsService;\n"],"file":"SegmentAnalyticsService.js"}
1
+ {"version":3,"sources":["../../src/analytics/SegmentAnalyticsService.js"],"names":["formurlencoded","snakeCaseObject","SegmentAnalyticsService","httpClient","loggingService","config","trackingLogApiUrl","LMS_BASE_URL","segmentKey","SEGMENT_KEY","hasIdentifyBeenCalled","segmentInitialized","initializeSegment","global","analytics","initialize","invoked","methods","factory","method","args","unshift","push","forEach","key","load","options","script","document","createElement","type","onerror","event","Event","dispatchEvent","async","src","first","getElementsByTagName","parentNode","insertBefore","_loadOptions","SNIPPET_VERSION","logError","eventName","properties","snakeEventData","deep","serverData","event_type","JSON","stringify","page","location","href","post","headers","error","userId","traits","Error","identify","Promise","resolve","reject","ready","user","id","reset","addEventListener","setTimeout","ga","create","checkIdentifyCalled","track","category","name"],"mappings":"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","sourcesContent":["import formurlencoded from 'form-urlencoded';\nimport { snakeCaseObject } from '../utils';\n\n/**\n * @implements {AnalyticsService}\n * @memberof module:Analytics\n */\nclass SegmentAnalyticsService {\n constructor({ httpClient, loggingService, config }) {\n this.loggingService = loggingService;\n this.httpClient = httpClient;\n this.trackingLogApiUrl = `${config.LMS_BASE_URL}/event`;\n this.segmentKey = config.SEGMENT_KEY;\n this.hasIdentifyBeenCalled = false;\n this.segmentInitialized = false;\n\n if (this.segmentKey) {\n this.initializeSegment();\n }\n }\n\n // The code in this function is from Segment's website, with a few updates:\n // - It uses the segmentKey from the SegmentAnalyticsService instance.\n // - It also saves a \"segmentInitialized\" variable on the SegmentAnalyticsService instance so\n // that the service can keep track of its own initialization state.\n // Reference:\n // https://segment.com/docs/connections/sources/catalog/libraries/website/javascript/quickstart/\n initializeSegment() {\n // Create a queue, but don't obliterate an existing one!\n global.analytics = global.analytics || [];\n const { analytics } = global;\n\n // If the real analytics.js is already on the page return.\n if (analytics.initialize) {\n this.segmentInitialized = true;\n return;\n }\n\n // If the snippet was invoked do nothing.\n if (analytics.invoked) {\n this.segmentInitialized = true;\n return;\n }\n\n // Invoked flag, to make sure the snippet\n // is never invoked twice.\n analytics.invoked = true;\n\n // A list of the methods in Analytics.js to stub.\n analytics.methods = [\n 'trackSubmit',\n 'trackClick',\n 'trackLink',\n 'trackForm',\n 'pageview',\n 'identify',\n 'reset',\n 'group',\n 'track',\n 'ready',\n 'alias',\n 'debug',\n 'page',\n 'once',\n 'off',\n 'on',\n ];\n\n // Define a factory to create stubs. These are placeholders\n // for methods in Analytics.js so that you never have to wait\n // for it to load to actually record data. The `method` is\n // stored as the first argument, so we can replay the data.\n analytics.factory = method => ((...args) => {\n args.unshift(method);\n analytics.push(args);\n return analytics;\n });\n\n // For each of our methods, generate a queueing stub.\n analytics.methods.forEach((key) => {\n analytics[key] = analytics.factory(key);\n });\n\n // Define a method to load Analytics.js from our CDN,\n // and that will be sure to only ever load it once.\n analytics.load = (key, options) => {\n // Create an async script element based on your key.\n const script = document.createElement('script');\n script.type = 'text/javascript';\n script.onerror = () => {\n this.segmentInitialized = false;\n const event = new Event('segmentFailed');\n document.dispatchEvent(event);\n };\n script.async = true;\n script.src = `https://cdn.segment.com/analytics.js/v1/${key}/analytics.min.js`;\n\n // Insert our script next to the first script element.\n const first = document.getElementsByTagName('script')[0];\n first.parentNode.insertBefore(script, first);\n analytics._loadOptions = options; // eslint-disable-line no-underscore-dangle\n\n this.segmentInitialized = true;\n };\n\n // Add a version to keep track of what's in the wild.\n analytics.SNIPPET_VERSION = '4.1.0';\n\n // Load Analytics.js with your key, which will automatically\n // load the tools you've enabled for your account. Boosh!\n analytics.load(this.segmentKey);\n }\n\n /**\n * Checks that identify was first called. Otherwise, logs error.\n *\n */\n checkIdentifyCalled() {\n if (!this.hasIdentifyBeenCalled) {\n this.loggingService.logError('Identify must be called before other tracking events.');\n }\n }\n\n /**\n * Logs events to tracking log and downstream.\n * For tracking log event documentation, see\n * https://openedx.atlassian.net/wiki/spaces/AN/pages/13205895/Event+Design+and+Review+Process\n *\n * @param {string} eventName (event_type on backend, but named to match Segment api)\n * @param {Object} properties (event on backend, but named properties to match Segment api)\n * @returns {Promise} The promise returned by HttpClient.post.\n */\n sendTrackingLogEvent(eventName, properties) {\n const snakeEventData = snakeCaseObject(properties, { deep: true });\n const serverData = {\n event_type: eventName,\n event: JSON.stringify(snakeEventData),\n page: global.location.href,\n };\n return this.httpClient.post(\n this.trackingLogApiUrl,\n formurlencoded(serverData),\n {\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n },\n ).catch((error) => {\n this.loggingService.logError(error);\n });\n }\n\n /**\n * * Send identify call to Segment.\n *\n * @param {string} userId\n * @param {*} [traits]\n */\n identifyAuthenticatedUser(userId, traits) {\n if (!userId) {\n throw new Error('UserId is required for identifyAuthenticatedUser.');\n }\n\n if (!this.segmentInitialized) {\n return;\n }\n global.analytics.identify(userId, traits);\n this.hasIdentifyBeenCalled = true;\n }\n\n /**\n * Send anonymous identify call to Segment's identify.\n *\n * @param {*} [traits]\n * @returns {Promise} Promise that will resolve once the document readyState is complete\n */\n identifyAnonymousUser(traits) {\n if (!this.segmentInitialized) {\n return Promise.resolve();\n }\n // if we do not have an authenticated user (indicated by being in this method),\n // but we still have a user id associated in segment, reset the local segment state\n // This has to be wrapped in the analytics.ready() callback because the analytics.user()\n // function isn't available until the analytics.js package has finished initializing.\n return new Promise((resolve, reject) => { // eslint-disable-line no-unused-vars\n global.analytics.ready(() => {\n if (global.analytics.user().id()) {\n global.analytics.reset();\n }\n global.analytics.identify(traits);\n this.hasIdentifyBeenCalled = true;\n resolve();\n });\n\n // this is added to handle a specific use-case where if a user has blocked the analytics\n // tools in their browser, this promise does not get resolved and user sees a blank\n // page. Dispatching this event in script.onerror callback in analytics.load.\n document.addEventListener('segmentFailed', resolve);\n // This is added to handle the google analytics blocked case which is injected into\n // the DOM by segment.min.js.\n setTimeout(() => {\n if (!global.ga || !global.ga.create) {\n this.segmentInitialized = false;\n resolve();\n }\n }, 2000);\n });\n }\n\n /**\n * Sends a track event to Segment and downstream.\n * Note: For links and forms, you should use trackLink and trackForm instead.\n *\n * @param {*} eventName\n * @param {*} [properties]\n */\n sendTrackEvent(eventName, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.track(eventName, properties);\n }\n\n /**\n * Sends a page event to Segment and downstream.\n *\n * @param {*} [name] If only one string arg provided, assumed to be name.\n * @param {*} [category] Name is required to pass a category.\n * @param {*} [properties]\n */\n sendPageEvent(category, name, properties) {\n if (!this.segmentInitialized) {\n return;\n }\n this.checkIdentifyCalled();\n global.analytics.page(category, name, properties);\n }\n}\n\nexport default SegmentAnalyticsService;\n"],"file":"SegmentAnalyticsService.js"}
package/config.js CHANGED
@@ -50,6 +50,7 @@ var config = {
50
50
  ENVIRONMENT: ENVIRONMENT,
51
51
  IGNORED_ERROR_REGEX: extractRegex(process.env.IGNORED_ERROR_REGEX),
52
52
  LANGUAGE_PREFERENCE_COOKIE_NAME: process.env.LANGUAGE_PREFERENCE_COOKIE_NAME,
53
+ LEARNING_BASE_URL: process.env.LEARNING_BASE_URL,
53
54
  LMS_BASE_URL: process.env.LMS_BASE_URL,
54
55
  LOGIN_URL: process.env.LOGIN_URL,
55
56
  LOGOUT_URL: process.env.LOGOUT_URL,
@@ -175,6 +176,7 @@ export function ensureConfig(keys) {
175
176
  * @property {string} ENVIRONMENT This is one of: development, production, or test.
176
177
  * @property {string} IGNORED_ERROR_REGEX
177
178
  * @property {string} LANGUAGE_PREFERENCE_COOKIE_NAME
179
+ * @property {string} LEARNING_BASE_URL
178
180
  * @property {string} LMS_BASE_URL
179
181
  * @property {string} LOGIN_URL
180
182
  * @property {string} LOGOUT_URL
package/config.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/config.js"],"names":["APP_CONFIG_INITIALIZED","CONFIG_CHANGED","publish","subscribe","ensureDefinedConfig","extractRegex","envVar","trim","RegExp","undefined","ENVIRONMENT","process","env","NODE_ENV","config","ACCESS_TOKEN_COOKIE_NAME","BASE_URL","PUBLIC_PATH","CREDENTIALS_BASE_URL","CSRF_TOKEN_API_PATH","DISCOVERY_API_BASE_URL","PUBLISHER_BASE_URL","ECOMMERCE_BASE_URL","IGNORED_ERROR_REGEX","LANGUAGE_PREFERENCE_COOKIE_NAME","LMS_BASE_URL","LOGIN_URL","LOGOUT_URL","STUDIO_BASE_URL","MARKETING_SITE_BASE_URL","ORDER_HISTORY_URL","REFRESH_ACCESS_TOKEN_ENDPOINT","SECURE_COOKIES","SEGMENT_KEY","SITE_NAME","USER_INFO_COOKIE_NAME","LOGO_URL","LOGO_TRADEMARK_URL","LOGO_WHITE_URL","FAVICON_URL","getConfig","setConfig","newConfig","mergeConfig","Object","assign","ensureConfig","keys","requester","forEach","key","console","warn"],"mappings":"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sB4B,SAAtB,CAAT;AACAxC,EAAAA,OAAO,CAACD,cAAD,CAAP;AACD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,OAAO,SAAS6C,YAAT,CAAsBC,IAAtB,EAAwE;AAAA,MAA5CC,SAA4C,uEAAhC,8BAAgC;AAC7E7C,EAAAA,SAAS,CAACH,sBAAD,EAAyB,YAAM;AACtC+C,IAAAA,IAAI,CAACE,OAAL,CAAa,UAACC,GAAD,EAAS;AACpB,UAAIpC,MAAM,CAACoC,GAAD,CAAN,KAAgBzC,SAApB,EAA+B;AAC7B;AACA0C,QAAAA,OAAO,CAACC,IAAR,oCAAyCF,GAAzC,6BAA+DF,SAA/D;AACD;AACF,KALD;AAMD,GAPQ,CAAT;AAQD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourcesContent":["/**\n * #### Import members from **@edx/frontend-platform**\n *\n * The configuration module provides utilities for working with an application's configuration\n * document (ConfigDocument). This module uses `process.env` to import configuration variables\n * from the command-line build process. It can be dynamically extended at run-time using a\n * `config` initialization handler. Please see the Initialization documentation for more\n * information on handlers and initialization phases.\n *\n * ```\n * import { getConfig } from '@edx/frontend-platform';\n *\n * const {\n * BASE_URL,\n * LMS_BASE_URL,\n * LOGIN_URL,\n * LOGIN_URL,\n * REFRESH_ACCESS_TOKEN_ENDPOINT,\n * ACCESS_TOKEN_COOKIE_NAME,\n * CSRF_TOKEN_API_PATH,\n * } = getConfig();\n * ```\n *\n * @module Config\n */\n\nimport { APP_CONFIG_INITIALIZED, CONFIG_CHANGED } from './constants';\n\nimport { publish, subscribe } from './pubSub';\nimport { ensureDefinedConfig } from './utils';\n\nfunction extractRegex(envVar) {\n // Convert the environment variable string to a regex, while guarding\n // against a non-string and an empty/whitespace-only string.\n if (typeof envVar === 'string' && envVar.trim() !== '') {\n return new RegExp(envVar);\n }\n return undefined;\n}\n\nconst ENVIRONMENT = process.env.NODE_ENV;\nlet config = {\n ACCESS_TOKEN_COOKIE_NAME: process.env.ACCESS_TOKEN_COOKIE_NAME,\n BASE_URL: process.env.BASE_URL,\n PUBLIC_PATH: process.env.PUBLIC_PATH || '/',\n CREDENTIALS_BASE_URL: process.env.CREDENTIALS_BASE_URL,\n CSRF_TOKEN_API_PATH: process.env.CSRF_TOKEN_API_PATH,\n DISCOVERY_API_BASE_URL: process.env.DISCOVERY_API_BASE_URL,\n PUBLISHER_BASE_URL: process.env.PUBLISHER_BASE_URL,\n ECOMMERCE_BASE_URL: process.env.ECOMMERCE_BASE_URL,\n ENVIRONMENT,\n IGNORED_ERROR_REGEX: extractRegex(process.env.IGNORED_ERROR_REGEX),\n LANGUAGE_PREFERENCE_COOKIE_NAME: process.env.LANGUAGE_PREFERENCE_COOKIE_NAME,\n LMS_BASE_URL: process.env.LMS_BASE_URL,\n LOGIN_URL: process.env.LOGIN_URL,\n LOGOUT_URL: process.env.LOGOUT_URL,\n STUDIO_BASE_URL: process.env.STUDIO_BASE_URL,\n MARKETING_SITE_BASE_URL: process.env.MARKETING_SITE_BASE_URL,\n ORDER_HISTORY_URL: process.env.ORDER_HISTORY_URL,\n REFRESH_ACCESS_TOKEN_ENDPOINT: process.env.REFRESH_ACCESS_TOKEN_ENDPOINT,\n SECURE_COOKIES: ENVIRONMENT !== 'development',\n SEGMENT_KEY: process.env.SEGMENT_KEY,\n SITE_NAME: process.env.SITE_NAME,\n USER_INFO_COOKIE_NAME: process.env.USER_INFO_COOKIE_NAME,\n LOGO_URL: process.env.LOGO_URL,\n LOGO_TRADEMARK_URL: process.env.LOGO_TRADEMARK_URL,\n LOGO_WHITE_URL: process.env.LOGO_WHITE_URL,\n FAVICON_URL: process.env.FAVICON_URL,\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. The document\n * should have the following keys at a minimum:\n *\n * @returns {ConfigDocument}\n */\nexport function getConfig() {\n return config;\n}\n\n/**\n * Replaces the existing ConfigDocument. This is not commonly used, but can be helpful for tests.\n *\n * The supplied config document will be tested with `ensureDefinedConfig` to ensure it does not\n * have any `undefined` keys.\n *\n * @param {ConfigDocument} newConfig\n */\nexport function setConfig(newConfig) {\n ensureDefinedConfig(config, 'config');\n config = newConfig;\n publish(CONFIG_CHANGED);\n}\n\n/**\n * Merges additional configuration values into the ConfigDocument returned by `getConfig`. Will\n * override any values that exist with the same keys.\n *\n * ```\n * mergeConfig({\n * NEW_KEY: 'new value',\n * OTHER_NEW_KEY: 'other new value',\n * });\n *\n * If any of the key values are `undefined`, an error will be logged to 'warn'.\n *\n * @param {Object} newConfig\n */\nexport function mergeConfig(newConfig) {\n ensureDefinedConfig(newConfig, 'ProcessEnvConfigService');\n config = Object.assign(config, newConfig);\n publish(CONFIG_CHANGED);\n}\n\n/**\n * A method allowing application code to indicate that particular ConfigDocument keys are required\n * for them to function. This is useful for diagnosing development/deployment issues, primarily,\n * by surfacing misconfigurations early. For instance, if the build process fails to supply an\n * environment variable on the command-line, it's possible that one of the `process.env` variables\n * will be undefined. Should be used in conjunction with `mergeConfig` for custom `ConfigDocument`\n * properties. Requester is for informational/error reporting purposes only.\n *\n * ```\n * ensureConfig(['LMS_BASE_URL', 'LOGIN_URL'], 'MySpecialComponent');\n *\n * // Will log a warning with:\n * // \"App configuration error: LOGIN_URL is required by MySpecialComponent.\"\n * // if LOGIN_URL is undefined, for example.\n * ```\n *\n * *NOTE*: `ensureConfig` waits until `APP_CONFIG_INITIALIZED` is published to verify the existence\n * of the specified properties. This means that this function is compatible with custom `config`\n * phase handlers responsible for loading additional configuration data in the initialization\n * sequence.\n *\n * @param {Array} keys\n * @param {string} [requester='unspecified application code']\n */\nexport function ensureConfig(keys, requester = 'unspecified application code') {\n subscribe(APP_CONFIG_INITIALIZED, () => {\n keys.forEach((key) => {\n if (config[key] === undefined) {\n // eslint-disable-next-line no-console\n console.warn(`App configuration error: ${key} is required by ${requester}.`);\n }\n });\n });\n}\n\n/**\n * An object describing the current application configuration.\n *\n * The implementation loads this document via `process.env` variables.\n *\n * ```\n * {\n * BASE_URL: process.env.BASE_URL,\n * // ... other vars\n * }\n * ```\n *\n * When using Webpack (i.e., normal usage), the build process is responsible for supplying these\n * variables via command-line environment variables. That means they must be supplied at build\n * time.\n *\n * @name ConfigDocument\n * @memberof module:Config\n * @property {string} ACCESS_TOKEN_COOKIE_NAME\n * @property {string} BASE_URL The URL of the current application.\n * @property {string} CREDENTIALS_BASE_URL\n * @property {string} CSRF_TOKEN_API_PATH\n * @property {string} DISCOVERY_API_BASE_URL\n * @property {string} PUBLISHER_BASE_URL\n * @property {string} ECOMMERCE_BASE_URL\n * @property {string} ENVIRONMENT This is one of: development, production, or test.\n * @property {string} IGNORED_ERROR_REGEX\n * @property {string} LANGUAGE_PREFERENCE_COOKIE_NAME\n * @property {string} LMS_BASE_URL\n * @property {string} LOGIN_URL\n * @property {string} LOGOUT_URL\n * @property {string} STUDIO_BASE_URL\n * @property {string} MARKETING_SITE_BASE_URL\n * @property {string} ORDER_HISTORY_URL\n * @property {string} REFRESH_ACCESS_TOKEN_ENDPOINT\n * @property {boolean} SECURE_COOKIES\n * @property {string} SEGMENT_KEY\n * @property {string} SITE_NAME\n * @property {string} USER_INFO_COOKIE_NAME\n * @property {string} LOGO_URL\n * @property {string} LOGO_TRADEMARK_URL\n * @property {string} LOGO_WHITE_URL\n * @property {string} FAVICON_URL\n */\n"],"file":"config.js"}
1
+ {"version":3,"sources":["../src/config.js"],"names":["APP_CONFIG_INITIALIZED","CONFIG_CHANGED","publish","subscribe","ensureDefinedConfig","extractRegex","envVar","trim","RegExp","undefined","ENVIRONMENT","process","env","NODE_ENV","config","ACCESS_TOKEN_COOKIE_NAME","BASE_URL","PUBLIC_PATH","CREDENTIALS_BASE_URL","CSRF_TOKEN_API_PATH","DISCOVERY_API_BASE_URL","PUBLISHER_BASE_URL","ECOMMERCE_BASE_URL","IGNORED_ERROR_REGEX","LANGUAGE_PREFERENCE_COOKIE_NAME","LEARNING_BASE_URL","LMS_BASE_URL","LOGIN_URL","LOGOUT_URL","STUDIO_BASE_URL","MARKETING_SITE_BASE_URL","ORDER_HISTORY_URL","REFRESH_ACCESS_TOKEN_ENDPOINT","SECURE_COOKIES","SEGMENT_KEY","SITE_NAME","USER_INFO_COOKIE_NAME","LOGO_URL","LOGO_TRADEMARK_URL","LOGO_WHITE_URL","FAVICON_URL","getConfig","setConfig","newConfig","mergeConfig","Object","assign","ensureConfig","keys","requester","forEach","key","console","warn"],"mappings":"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B;AACA7B,EAAAA,MAAM,GAAG+B,MAAM,CAACC,MAAP,CAAchC,MAAd,EAAsB6B,SAAtB,CAAT;AACAzC,EAAAA,OAAO,CAACD,cAAD,CAAP;AACD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AACA,OAAO,SAAS8C,YAAT,CAAsBC,IAAtB,EAAwE;AAAA,MAA5CC,SAA4C,uEAAhC,8BAAgC;AAC7E9C,EAAAA,SAAS,CAACH,sBAAD,EAAyB,YAAM;AACtCgD,IAAAA,IAAI,CAACE,OAAL,CAAa,UAACC,GAAD,EAAS;AACpB,UAAIrC,MAAM,CAACqC,GAAD,CAAN,KAAgB1C,SAApB,EAA+B;AAC7B;AACA2C,QAAAA,OAAO,CAACC,IAAR,oCAAyCF,GAAzC,6BAA+DF,SAA/D;AACD;AACF,KALD;AAMD,GAPQ,CAAT;AAQD;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","sourcesContent":["/**\n * #### Import members from **@edx/frontend-platform**\n *\n * The configuration module provides utilities for working with an application's configuration\n * document (ConfigDocument). This module uses `process.env` to import configuration variables\n * from the command-line build process. It can be dynamically extended at run-time using a\n * `config` initialization handler. Please see the Initialization documentation for more\n * information on handlers and initialization phases.\n *\n * ```\n * import { getConfig } from '@edx/frontend-platform';\n *\n * const {\n * BASE_URL,\n * LMS_BASE_URL,\n * LOGIN_URL,\n * LOGIN_URL,\n * REFRESH_ACCESS_TOKEN_ENDPOINT,\n * ACCESS_TOKEN_COOKIE_NAME,\n * CSRF_TOKEN_API_PATH,\n * } = getConfig();\n * ```\n *\n * @module Config\n */\n\nimport { APP_CONFIG_INITIALIZED, CONFIG_CHANGED } from './constants';\n\nimport { publish, subscribe } from './pubSub';\nimport { ensureDefinedConfig } from './utils';\n\nfunction extractRegex(envVar) {\n // Convert the environment variable string to a regex, while guarding\n // against a non-string and an empty/whitespace-only string.\n if (typeof envVar === 'string' && envVar.trim() !== '') {\n return new RegExp(envVar);\n }\n return undefined;\n}\n\nconst ENVIRONMENT = process.env.NODE_ENV;\nlet config = {\n ACCESS_TOKEN_COOKIE_NAME: process.env.ACCESS_TOKEN_COOKIE_NAME,\n BASE_URL: process.env.BASE_URL,\n PUBLIC_PATH: process.env.PUBLIC_PATH || '/',\n CREDENTIALS_BASE_URL: process.env.CREDENTIALS_BASE_URL,\n CSRF_TOKEN_API_PATH: process.env.CSRF_TOKEN_API_PATH,\n DISCOVERY_API_BASE_URL: process.env.DISCOVERY_API_BASE_URL,\n PUBLISHER_BASE_URL: process.env.PUBLISHER_BASE_URL,\n ECOMMERCE_BASE_URL: process.env.ECOMMERCE_BASE_URL,\n ENVIRONMENT,\n IGNORED_ERROR_REGEX: extractRegex(process.env.IGNORED_ERROR_REGEX),\n LANGUAGE_PREFERENCE_COOKIE_NAME: process.env.LANGUAGE_PREFERENCE_COOKIE_NAME,\n LEARNING_BASE_URL: process.env.LEARNING_BASE_URL,\n LMS_BASE_URL: process.env.LMS_BASE_URL,\n LOGIN_URL: process.env.LOGIN_URL,\n LOGOUT_URL: process.env.LOGOUT_URL,\n STUDIO_BASE_URL: process.env.STUDIO_BASE_URL,\n MARKETING_SITE_BASE_URL: process.env.MARKETING_SITE_BASE_URL,\n ORDER_HISTORY_URL: process.env.ORDER_HISTORY_URL,\n REFRESH_ACCESS_TOKEN_ENDPOINT: process.env.REFRESH_ACCESS_TOKEN_ENDPOINT,\n SECURE_COOKIES: ENVIRONMENT !== 'development',\n SEGMENT_KEY: process.env.SEGMENT_KEY,\n SITE_NAME: process.env.SITE_NAME,\n USER_INFO_COOKIE_NAME: process.env.USER_INFO_COOKIE_NAME,\n LOGO_URL: process.env.LOGO_URL,\n LOGO_TRADEMARK_URL: process.env.LOGO_TRADEMARK_URL,\n LOGO_WHITE_URL: process.env.LOGO_WHITE_URL,\n FAVICON_URL: process.env.FAVICON_URL,\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. The document\n * should have the following keys at a minimum:\n *\n * @returns {ConfigDocument}\n */\nexport function getConfig() {\n return config;\n}\n\n/**\n * Replaces the existing ConfigDocument. This is not commonly used, but can be helpful for tests.\n *\n * The supplied config document will be tested with `ensureDefinedConfig` to ensure it does not\n * have any `undefined` keys.\n *\n * @param {ConfigDocument} newConfig\n */\nexport function setConfig(newConfig) {\n ensureDefinedConfig(config, 'config');\n config = newConfig;\n publish(CONFIG_CHANGED);\n}\n\n/**\n * Merges additional configuration values into the ConfigDocument returned by `getConfig`. Will\n * override any values that exist with the same keys.\n *\n * ```\n * mergeConfig({\n * NEW_KEY: 'new value',\n * OTHER_NEW_KEY: 'other new value',\n * });\n *\n * If any of the key values are `undefined`, an error will be logged to 'warn'.\n *\n * @param {Object} newConfig\n */\nexport function mergeConfig(newConfig) {\n ensureDefinedConfig(newConfig, 'ProcessEnvConfigService');\n config = Object.assign(config, newConfig);\n publish(CONFIG_CHANGED);\n}\n\n/**\n * A method allowing application code to indicate that particular ConfigDocument keys are required\n * for them to function. This is useful for diagnosing development/deployment issues, primarily,\n * by surfacing misconfigurations early. For instance, if the build process fails to supply an\n * environment variable on the command-line, it's possible that one of the `process.env` variables\n * will be undefined. Should be used in conjunction with `mergeConfig` for custom `ConfigDocument`\n * properties. Requester is for informational/error reporting purposes only.\n *\n * ```\n * ensureConfig(['LMS_BASE_URL', 'LOGIN_URL'], 'MySpecialComponent');\n *\n * // Will log a warning with:\n * // \"App configuration error: LOGIN_URL is required by MySpecialComponent.\"\n * // if LOGIN_URL is undefined, for example.\n * ```\n *\n * *NOTE*: `ensureConfig` waits until `APP_CONFIG_INITIALIZED` is published to verify the existence\n * of the specified properties. This means that this function is compatible with custom `config`\n * phase handlers responsible for loading additional configuration data in the initialization\n * sequence.\n *\n * @param {Array} keys\n * @param {string} [requester='unspecified application code']\n */\nexport function ensureConfig(keys, requester = 'unspecified application code') {\n subscribe(APP_CONFIG_INITIALIZED, () => {\n keys.forEach((key) => {\n if (config[key] === undefined) {\n // eslint-disable-next-line no-console\n console.warn(`App configuration error: ${key} is required by ${requester}.`);\n }\n });\n });\n}\n\n/**\n * An object describing the current application configuration.\n *\n * The implementation loads this document via `process.env` variables.\n *\n * ```\n * {\n * BASE_URL: process.env.BASE_URL,\n * // ... other vars\n * }\n * ```\n *\n * When using Webpack (i.e., normal usage), the build process is responsible for supplying these\n * variables via command-line environment variables. That means they must be supplied at build\n * time.\n *\n * @name ConfigDocument\n * @memberof module:Config\n * @property {string} ACCESS_TOKEN_COOKIE_NAME\n * @property {string} BASE_URL The URL of the current application.\n * @property {string} CREDENTIALS_BASE_URL\n * @property {string} CSRF_TOKEN_API_PATH\n * @property {string} DISCOVERY_API_BASE_URL\n * @property {string} PUBLISHER_BASE_URL\n * @property {string} ECOMMERCE_BASE_URL\n * @property {string} ENVIRONMENT This is one of: development, production, or test.\n * @property {string} IGNORED_ERROR_REGEX\n * @property {string} LANGUAGE_PREFERENCE_COOKIE_NAME\n * @property {string} LEARNING_BASE_URL\n * @property {string} LMS_BASE_URL\n * @property {string} LOGIN_URL\n * @property {string} LOGOUT_URL\n * @property {string} STUDIO_BASE_URL\n * @property {string} MARKETING_SITE_BASE_URL\n * @property {string} ORDER_HISTORY_URL\n * @property {string} REFRESH_ACCESS_TOKEN_ENDPOINT\n * @property {boolean} SECURE_COOKIES\n * @property {string} SEGMENT_KEY\n * @property {string} SITE_NAME\n * @property {string} USER_INFO_COOKIE_NAME\n * @property {string} LOGO_URL\n * @property {string} LOGO_TRADEMARK_URL\n * @property {string} LOGO_WHITE_URL\n * @property {string} FAVICON_URL\n */\n"],"file":"config.js"}
@@ -58,7 +58,7 @@ if (process.argv[3] === '--comments') {
58
58
  // prepare to handle the translator notes
59
59
  var loggingPrefix = path.basename("".concat(__filename)); // the name of this JS file
60
60
 
61
- var bashScriptsPath = './node_modules/reactifex/bash_scripts';
61
+ var bashScriptsPath = process.argv[4] && process.argv[4] === '--v3-scripts-path' ? './node_modules/@edx/reactifex/bash_scripts' : './node_modules/reactifex/bash_scripts';
62
62
  var hashFile = "".concat(bashScriptsPath, "/hashmap.json");
63
63
  process.stdout.write("".concat(loggingPrefix, ": reading hash file ").concat(hashFile, "\n"));
64
64
  var messageInfo = JSON.parse(fs.readFileSync(hashFile));
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/i18n/scripts/transifex-utils.js"],"names":["fs","require","glob","path","gatherJson","dir","ret","files","sync","forEach","filename","messages","JSON","parse","readFileSync","push","escapeDots","messageId","replace","jsonDir","process","argv","messageObjects","length","exitCode","Error","loggingPrefix","basename","__filename","bashScriptsPath","hashFile","stdout","write","messageInfo","outputFile","writeFileSync","message","transifexFormatId","id","info","find","mi","key","appendFileSync","string_hash","description","output","defaultMessage","stringify"],"mappings":"AAAA;;;;;;;;;;;;;;AAEA,IAAMA,EAAE,GAAGC,OAAO,CAAC,IAAD,CAAlB;;AACA,IAAMC,IAAI,GAAGD,OAAO,CAAC,MAAD,CAApB;;AACA,IAAME,IAAI,GAAGF,OAAO,CAAC,MAAD,CAApB;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;;;AACA,SAASG,UAAT,CAAoBC,GAApB,EAAyB;AACvB,MAAMC,GAAG,GAAG,EAAZ;AACA,MAAMC,KAAK,GAAGL,IAAI,CAACM,IAAL,WAAaH,GAAb,gBAAd;AAEAE,EAAAA,KAAK,CAACE,OAAN,CAAc,UAACC,QAAD,EAAc;AAC1B,QAAMC,QAAQ,GAAGC,IAAI,CAACC,KAAL,CAAWb,EAAE,CAACc,YAAH,CAAgBJ,QAAhB,CAAX,CAAjB;AACAJ,IAAAA,GAAG,CAACS,IAAJ,OAAAT,GAAG,qBAASK,QAAT,EAAH;AACD,GAHD;AAIA,SAAOL,GAAP;AACD,C,CAED;AACA;AACA;;;AACA,SAASU,UAAT,CAAoBC,SAApB,EAA+B;AAC7B,SAAOA,SAAS,CAACC,OAAV,CAAkB,KAAlB,EAAyB,KAAzB,CAAP;AACD;;AAED,IAAMC,OAAO,GAAGC,OAAO,CAACC,IAAR,CAAa,CAAb,CAAhB;AACA,IAAMC,cAAc,GAAGlB,UAAU,CAACe,OAAD,CAAjC;;AAEA,IAAIG,cAAc,CAACC,MAAf,KAA0B,CAA9B,EAAiC;AAC/BH,EAAAA,OAAO,CAACI,QAAR,GAAmB,CAAnB;AACA,QAAM,IAAIC,KAAJ,CAAU,mBAAV,CAAN;AACD;;AAED,IAAIL,OAAO,CAACC,IAAR,CAAa,CAAb,MAAoB,YAAxB,EAAsC;AAAE;AACtC,MAAMK,aAAa,GAAGvB,IAAI,CAACwB,QAAL,WAAiBC,UAAjB,EAAtB,CADoC,CACkB;;AACtD,MAAMC,eAAe,GAAG,uCAAxB;AAEA,MAAMC,QAAQ,aAAMD,eAAN,kBAAd;AACAT,EAAAA,OAAO,CAACW,MAAR,CAAeC,KAAf,WAAwBN,aAAxB,iCAA4DI,QAA5D;AACA,MAAMG,WAAW,GAAGrB,IAAI,CAACC,KAAL,CAAWb,EAAE,CAACc,YAAH,CAAgBgB,QAAhB,CAAX,CAApB;AAEA,MAAMI,UAAU,aAAML,eAAN,qBAAhB;AACAT,EAAAA,OAAO,CAACW,MAAR,CAAeC,KAAf,WAAwBN,aAAxB,sCAAiEQ,UAAjE;AACAlC,EAAAA,EAAE,CAACmC,aAAH,CAAiBD,UAAjB,EAA6B,EAA7B;AAEAZ,EAAAA,cAAc,CAACb,OAAf,CAAuB,UAAC2B,OAAD,EAAa;AAClC,QAAMC,iBAAiB,GAAGrB,UAAU,CAACoB,OAAO,CAACE,EAAT,CAApC;AAEA,QAAMC,IAAI,GAAGN,WAAW,CAACO,IAAZ,CAAiB,UAAAC,EAAE;AAAA,aAAIA,EAAE,CAACC,GAAH,KAAWL,iBAAf;AAAA,KAAnB,CAAb;;AACA,QAAIE,IAAJ,EAAU;AACRvC,MAAAA,EAAE,CAAC2C,cAAH,CAAkBT,UAAlB,YAAiCK,IAAI,CAACK,WAAtC,cAAqDR,OAAO,CAACS,WAA7D;AACD,KAFD,MAEO;AACLzB,MAAAA,OAAO,CAACW,MAAR,CAAeC,KAAf,WAAwBN,aAAxB,sBAAiDU,OAAO,CAACE,EAAzD;AACD;AACF,GATD;AAUD,CAtBD,MAsBO;AACL,MAAMQ,MAAM,GAAG,EAAf;AAEAxB,EAAAA,cAAc,CAACb,OAAf,CAAuB,UAAC2B,OAAD,EAAa;AAClCU,IAAAA,MAAM,CAACV,OAAO,CAACE,EAAT,CAAN,GAAqBF,OAAO,CAACW,cAA7B;AACD,GAFD;AAGA/C,EAAAA,EAAE,CAACmC,aAAH,CAAiBf,OAAO,CAACC,IAAR,CAAa,CAAb,CAAjB,EAAkCT,IAAI,CAACoC,SAAL,CAAeF,MAAf,EAAuB,IAAvB,EAA6B,CAA7B,CAAlC;AACD","sourcesContent":["#!/usr/bin/env node\n\nconst fs = require('fs');\nconst glob = require('glob');\nconst path = require('path');\n\n/*\n * See the Makefile for how the required hash file is downloaded from Transifex.\n */\n\n/*\n * Expected input: a directory, possibly containing subdirectories, with .json files. Each .json\n * file is an array of translation triplets (id, description, defaultMessage).\n *\n *\n */\nfunction gatherJson(dir) {\n const ret = [];\n const files = glob.sync(`${dir}/**/*.json`);\n\n files.forEach((filename) => {\n const messages = JSON.parse(fs.readFileSync(filename));\n ret.push(...messages);\n });\n return ret;\n}\n\n// the hash file returns ids whose periods are \"escaped\" (sort of), like this:\n// \"key\": \"profile\\\\.sociallinks\\\\.social\\\\.links\"\n// so our regular messageIds won't match them out of the box\nfunction escapeDots(messageId) {\n return messageId.replace(/\\./g, '\\\\.');\n}\n\nconst jsonDir = process.argv[2];\nconst messageObjects = gatherJson(jsonDir);\n\nif (messageObjects.length === 0) {\n process.exitCode = 1;\n throw new Error('Found no messages');\n}\n\nif (process.argv[3] === '--comments') { // prepare to handle the translator notes\n const loggingPrefix = path.basename(`${__filename}`); // the name of this JS file\n const bashScriptsPath = './node_modules/reactifex/bash_scripts';\n\n const hashFile = `${bashScriptsPath}/hashmap.json`;\n process.stdout.write(`${loggingPrefix}: reading hash file ${hashFile}\\n`);\n const messageInfo = JSON.parse(fs.readFileSync(hashFile));\n\n const outputFile = `${bashScriptsPath}/hashed_data.txt`;\n process.stdout.write(`${loggingPrefix}: writing to output file ${outputFile}\\n`);\n fs.writeFileSync(outputFile, '');\n\n messageObjects.forEach((message) => {\n const transifexFormatId = escapeDots(message.id);\n\n const info = messageInfo.find(mi => mi.key === transifexFormatId);\n if (info) {\n fs.appendFileSync(outputFile, `${info.string_hash}|${message.description}\\n`);\n } else {\n process.stdout.write(`${loggingPrefix}: string ${message.id} does not yet exist on transifex!\\n`);\n }\n });\n} else {\n const output = {};\n\n messageObjects.forEach((message) => {\n output[message.id] = message.defaultMessage;\n });\n fs.writeFileSync(process.argv[3], JSON.stringify(output, null, 2));\n}\n"],"file":"transifex-utils.js"}
1
+ {"version":3,"sources":["../../../src/i18n/scripts/transifex-utils.js"],"names":["fs","require","glob","path","gatherJson","dir","ret","files","sync","forEach","filename","messages","JSON","parse","readFileSync","push","escapeDots","messageId","replace","jsonDir","process","argv","messageObjects","length","exitCode","Error","loggingPrefix","basename","__filename","bashScriptsPath","hashFile","stdout","write","messageInfo","outputFile","writeFileSync","message","transifexFormatId","id","info","find","mi","key","appendFileSync","string_hash","description","output","defaultMessage","stringify"],"mappings":"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","sourcesContent":["#!/usr/bin/env node\n\nconst fs = require('fs');\nconst glob = require('glob');\nconst path = require('path');\n\n/*\n * See the Makefile for how the required hash file is downloaded from Transifex.\n */\n\n/*\n * Expected input: a directory, possibly containing subdirectories, with .json files. Each .json\n * file is an array of translation triplets (id, description, defaultMessage).\n *\n *\n */\nfunction gatherJson(dir) {\n const ret = [];\n const files = glob.sync(`${dir}/**/*.json`);\n\n files.forEach((filename) => {\n const messages = JSON.parse(fs.readFileSync(filename));\n ret.push(...messages);\n });\n return ret;\n}\n\n// the hash file returns ids whose periods are \"escaped\" (sort of), like this:\n// \"key\": \"profile\\\\.sociallinks\\\\.social\\\\.links\"\n// so our regular messageIds won't match them out of the box\nfunction escapeDots(messageId) {\n return messageId.replace(/\\./g, '\\\\.');\n}\n\nconst jsonDir = process.argv[2];\nconst messageObjects = gatherJson(jsonDir);\n\nif (messageObjects.length === 0) {\n process.exitCode = 1;\n throw new Error('Found no messages');\n}\n\nif (process.argv[3] === '--comments') { // prepare to handle the translator notes\n const loggingPrefix = path.basename(`${__filename}`); // the name of this JS file\n const bashScriptsPath = (\n process.argv[4] && process.argv[4] === '--v3-scripts-path'\n ? './node_modules/@edx/reactifex/bash_scripts'\n : './node_modules/reactifex/bash_scripts');\n\n const hashFile = `${bashScriptsPath}/hashmap.json`;\n process.stdout.write(`${loggingPrefix}: reading hash file ${hashFile}\\n`);\n const messageInfo = JSON.parse(fs.readFileSync(hashFile));\n\n const outputFile = `${bashScriptsPath}/hashed_data.txt`;\n process.stdout.write(`${loggingPrefix}: writing to output file ${outputFile}\\n`);\n fs.writeFileSync(outputFile, '');\n\n messageObjects.forEach((message) => {\n const transifexFormatId = escapeDots(message.id);\n\n const info = messageInfo.find(mi => mi.key === transifexFormatId);\n if (info) {\n fs.appendFileSync(outputFile, `${info.string_hash}|${message.description}\\n`);\n } else {\n process.stdout.write(`${loggingPrefix}: string ${message.id} does not yet exist on transifex!\\n`);\n }\n });\n} else {\n const output = {};\n\n messageObjects.forEach((message) => {\n output[message.id] = message.defaultMessage;\n });\n fs.writeFileSync(process.argv[3], JSON.stringify(output, null, 2));\n}\n"],"file":"transifex-utils.js"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edx/frontend-platform",
3
- "version": "1.12.6",
3
+ "version": "1.14.0",
4
4
  "description": "Foundational application framework for Open edX micro-frontend applications.",
5
5
  "main": "index.js",
6
6
  "publishConfig": {
@@ -31,23 +31,21 @@
31
31
  },
32
32
  "homepage": "https://github.com/edx/frontend-platform#readme",
33
33
  "devDependencies": {
34
- "@commitlint/cli": "13.1.0",
35
- "@commitlint/config-angular": "13.1.0",
36
34
  "@edx/brand": "npm:@edx/brand-openedx@1.1.0",
37
- "@edx/frontend-build": "8.0.4",
38
- "@edx/paragon": "16.11.0",
35
+ "@edx/frontend-build": "8.0.6",
36
+ "@edx/paragon": "16.15.1",
39
37
  "axios-mock-adapter": "1.20.0",
40
38
  "codecov": "3.8.3",
41
- "core-js": "3.16.4",
39
+ "core-js": "3.18.3",
42
40
  "enzyme": "3.11.0",
43
41
  "enzyme-adapter-react-16": "1.15.6",
44
- "husky": "7.0.2",
42
+ "husky": "7.0.4",
45
43
  "jsdoc": "3.6.7",
46
- "nodemon": "2.0.12",
44
+ "nodemon": "2.0.14",
47
45
  "prop-types": "15.7.2",
48
46
  "react": "16.14.0",
49
47
  "react-dom": "16.14.0",
50
- "react-redux": "7.2.5",
48
+ "react-redux": "7.2.6",
51
49
  "react-router-dom": "5.2.0",
52
50
  "redux": "4.1.1",
53
51
  "regenerator-runtime": "0.13.9"