@staffbase/plugins-client-sdk 2.0.1 → 3.0.0-alpha.2

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.
@@ -2,12 +2,12 @@
2
2
  * Bundle of @staffbase/plugins-client-sdk
3
3
  * @file Staffbase plugins client SDK for JavaScript
4
4
  * @see https://github.com/Staffbase/plugins-client-sdk#readme
5
- * @version 2.0.0
5
+ * @version 3.0.0-alpha.2
6
6
  *
7
7
  * @author Stefan Staude <stefan.staude@staffbase.com>
8
8
  * @author Daniel Große <daniel.grosse@staffbase.com>
9
9
  *
10
- * @copyright 2023
10
+ * @copyright 2026
11
11
  * @license Apache-2.0
12
12
  */
13
13
 
@@ -46,6 +46,8 @@
46
46
  var undefinedType = "undefined";
47
47
  var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
48
48
  var logMethods = ["trace", "debug", "info", "warn", "error"];
49
+ var _loggersByName = {};
50
+ var defaultLogger = null;
49
51
 
50
52
  // Cross-browser bind equivalent that works at least back to IE6
51
53
  function bindMethod(obj, methodName) {
@@ -98,23 +100,31 @@
98
100
 
99
101
  // These private functions always need `this` to be set properly
100
102
 
101
- function replaceLoggingMethods(level, loggerName) {
103
+ function replaceLoggingMethods() {
102
104
  /*jshint validthis:true */
105
+ var level = this.getLevel();
106
+
107
+ // Replace the actual methods.
103
108
  for (var i = 0; i < logMethods.length; i++) {
104
109
  var methodName = logMethods[i];
105
- this[methodName] = i < level ? noop : this.methodFactory(methodName, level, loggerName);
110
+ this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
106
111
  }
107
112
 
108
113
  // Define log.log as an alias for log.debug
109
114
  this.log = this.debug;
115
+
116
+ // Return any important warnings.
117
+ if (typeof console === undefinedType && level < this.levels.SILENT) {
118
+ return "No console available for logging";
119
+ }
110
120
  }
111
121
 
112
122
  // In old IE versions, the console isn't present until you first open it.
113
123
  // We build realMethod() replacements here that regenerate logging methods
114
- function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {
124
+ function enableLoggingWhenConsoleArrives(methodName) {
115
125
  return function () {
116
126
  if (typeof console !== undefinedType) {
117
- replaceLoggingMethods.call(this, level, loggerName);
127
+ replaceLoggingMethods.call(this);
118
128
  this[methodName].apply(this, arguments);
119
129
  }
120
130
  };
@@ -122,14 +132,34 @@
122
132
 
123
133
  // By default, we use closely bound real methods wherever possible, and
124
134
  // otherwise we wait for a console to appear, and then try again.
125
- function defaultMethodFactory(methodName, level, loggerName) {
135
+ function defaultMethodFactory(methodName, _level, _loggerName) {
126
136
  /*jshint validthis:true */
127
137
  return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
128
138
  }
129
- function Logger(name, defaultLevel, factory) {
139
+ function Logger(name, factory) {
140
+ // Private instance variables.
130
141
  var self = this;
131
- var currentLevel;
132
- defaultLevel = defaultLevel == null ? "WARN" : defaultLevel;
142
+ /**
143
+ * The level inherited from a parent logger (or a global default). We
144
+ * cache this here rather than delegating to the parent so that it stays
145
+ * in sync with the actual logging methods that we have installed (the
146
+ * parent could change levels but we might not have rebuilt the loggers
147
+ * in this child yet).
148
+ * @type {number}
149
+ */
150
+ var inheritedLevel;
151
+ /**
152
+ * The default level for this logger, if any. If set, this overrides
153
+ * `inheritedLevel`.
154
+ * @type {number|null}
155
+ */
156
+ var defaultLevel;
157
+ /**
158
+ * A user-specific level for this logger. If set, this overrides
159
+ * `defaultLevel`.
160
+ * @type {number|null}
161
+ */
162
+ var userLevel;
133
163
  var storageKey = "loglevel";
134
164
  if (typeof name === "string") {
135
165
  storageKey += ":" + name;
@@ -162,9 +192,10 @@
162
192
  if (typeof storedLevel === undefinedType) {
163
193
  try {
164
194
  var cookie = window.document.cookie;
165
- var location = cookie.indexOf(encodeURIComponent(storageKey) + "=");
195
+ var cookieName = encodeURIComponent(storageKey);
196
+ var location = cookie.indexOf(cookieName + "=");
166
197
  if (location !== -1) {
167
- storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
198
+ storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
168
199
  }
169
200
  } catch (ignore) {}
170
201
  }
@@ -181,7 +212,6 @@
181
212
  // Use localStorage if available
182
213
  try {
183
214
  window.localStorage.removeItem(storageKey);
184
- return;
185
215
  } catch (ignore) {}
186
216
 
187
217
  // Use session cookie as fallback
@@ -189,6 +219,17 @@
189
219
  window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
190
220
  } catch (ignore) {}
191
221
  }
222
+ function normalizeLevel(input) {
223
+ var level = input;
224
+ if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
225
+ level = self.levels[level.toUpperCase()];
226
+ }
227
+ if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
228
+ return level;
229
+ } else {
230
+ throw new TypeError("log.setLevel() called with invalid level: " + input);
231
+ }
232
+ }
192
233
 
193
234
  /*
194
235
  *
@@ -207,46 +248,60 @@
207
248
  };
208
249
  self.methodFactory = factory || defaultMethodFactory;
209
250
  self.getLevel = function () {
210
- return currentLevel;
251
+ if (userLevel != null) {
252
+ return userLevel;
253
+ } else if (defaultLevel != null) {
254
+ return defaultLevel;
255
+ } else {
256
+ return inheritedLevel;
257
+ }
211
258
  };
212
259
  self.setLevel = function (level, persist) {
213
- if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
214
- level = self.levels[level.toUpperCase()];
215
- }
216
- if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
217
- currentLevel = level;
218
- if (persist !== false) {
219
- // defaults to true
220
- persistLevelIfPossible(level);
221
- }
222
- replaceLoggingMethods.call(self, level, name);
223
- if (typeof console === undefinedType && level < self.levels.SILENT) {
224
- return "No console available for logging";
225
- }
226
- } else {
227
- throw "log.setLevel() called with invalid level: " + level;
260
+ userLevel = normalizeLevel(level);
261
+ if (persist !== false) {
262
+ // defaults to true
263
+ persistLevelIfPossible(userLevel);
228
264
  }
265
+
266
+ // NOTE: in v2, this should call rebuild(), which updates children.
267
+ return replaceLoggingMethods.call(self);
229
268
  };
230
269
  self.setDefaultLevel = function (level) {
231
- defaultLevel = level;
270
+ defaultLevel = normalizeLevel(level);
232
271
  if (!getPersistedLevel()) {
233
272
  self.setLevel(level, false);
234
273
  }
235
274
  };
236
275
  self.resetLevel = function () {
237
- self.setLevel(defaultLevel, false);
276
+ userLevel = null;
238
277
  clearPersistedLevel();
278
+ replaceLoggingMethods.call(self);
279
+ };
280
+ self.enableAll = function (persist) {
281
+ self.setLevel(self.levels.TRACE, persist);
239
282
  };
240
283
  self.disableAll = function (persist) {
241
284
  self.setLevel(self.levels.SILENT, persist);
242
285
  };
286
+ self.rebuild = function () {
287
+ if (defaultLogger !== self) {
288
+ inheritedLevel = normalizeLevel(defaultLogger.getLevel());
289
+ }
290
+ replaceLoggingMethods.call(self);
291
+ if (defaultLogger === self) {
292
+ for (var childName in _loggersByName) {
293
+ _loggersByName[childName].rebuild();
294
+ }
295
+ }
296
+ };
243
297
 
244
- // Initialize with the right level
298
+ // Initialize all the internal levels.
299
+ inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
245
300
  var initialLevel = getPersistedLevel();
246
- if (initialLevel == null) {
247
- initialLevel = defaultLevel;
301
+ if (initialLevel != null) {
302
+ userLevel = normalizeLevel(initialLevel);
248
303
  }
249
- self.setLevel(initialLevel, false);
304
+ replaceLoggingMethods.call(self);
250
305
  }
251
306
 
252
307
  /*
@@ -255,15 +310,14 @@
255
310
  *
256
311
  */
257
312
 
258
- var defaultLogger = new Logger();
259
- var _loggersByName = {};
313
+ defaultLogger = new Logger();
260
314
  defaultLogger.getLogger = function getLogger(name) {
261
315
  if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
262
316
  throw new TypeError("You must supply a name when creating a logger.");
263
317
  }
264
318
  var logger = _loggersByName[name];
265
319
  if (!logger) {
266
- logger = _loggersByName[name] = new Logger(name, defaultLogger.getLevel(), defaultLogger.methodFactory);
320
+ logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
267
321
  }
268
322
  return logger;
269
323
  };
@@ -349,7 +403,8 @@
349
403
  nativeShare: 'nativeShareDialog',
350
404
  langInfos: 'getLanguageInfos',
351
405
  branchDefaultLang: 'getBranchDefaultLanguage',
352
- prefContentLang: 'getPreferredContentLocale'
406
+ prefContentLang: 'getPreferredContentLocale',
407
+ userContentLocale: 'getUserContentLocale'
353
408
  };
354
409
 
355
410
  /**
@@ -447,6 +502,12 @@
447
502
  name: 'English',
448
503
  localizedName: 'English'
449
504
  },
505
+ enGB: {
506
+ key: 'enGB',
507
+ locale: 'en_GB',
508
+ name: 'English (United Kingdom)',
509
+ localizedName: 'English (United Kingdom)'
510
+ },
450
511
  es: {
451
512
  key: 'es',
452
513
  locale: 'es_ES',
@@ -938,7 +999,17 @@
938
999
  }
939
1000
  };
940
1001
 
941
- let connection$2 = null;
1002
+ /**
1003
+ * Get the current user's content locale, fallback to branch default locale
1004
+ *
1005
+ * @return {String} the user's content locale
1006
+ */
1007
+ const getUserContentLocale$2 = () => {
1008
+ const locale = getBranchDefaultLanguage$2().locale;
1009
+ return locale;
1010
+ };
1011
+
1012
+ let connection$1 = null;
942
1013
  const fallbackKickIn = 500;
943
1014
 
944
1015
  /**
@@ -948,17 +1019,17 @@
948
1019
  * after the time specified in fallbackKickIn runs out.
949
1020
  * @return {Promise<function>} An appropriate send function
950
1021
  */
951
- var fallback = (() => {
952
- if (connection$2) {
953
- return connection$2;
1022
+ var fallback = () => {
1023
+ if (connection$1) {
1024
+ return connection$1;
954
1025
  }
955
- connection$2 = new Promise(resolve => {
1026
+ connection$1 = new Promise(resolve => {
956
1027
  setTimeout(function () {
957
- resolve(sendMessage$3);
1028
+ resolve(sendMessage$2);
958
1029
  }, fallbackKickIn);
959
1030
  });
960
- return connection$2;
961
- });
1031
+ return connection$1;
1032
+ };
962
1033
 
963
1034
  /**
964
1035
  * Send a SDK command to the Staffbase App.
@@ -969,7 +1040,7 @@
969
1040
  * @return {Promise<any>} which awaits the response of the Staffbase App
970
1041
  * @throws {Error} on commands not supported by protocol
971
1042
  */
972
- const sendMessage$3 = async function (cmd) {
1043
+ const sendMessage$2 = async function (cmd) {
973
1044
  for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
974
1045
  payload[_key - 1] = arguments[_key];
975
1046
  }
@@ -992,6 +1063,8 @@
992
1063
  return getBranchDefaultLanguage$2();
993
1064
  case commands.prefContentLang:
994
1065
  return getPreferredContentLocale$2.apply(null, payload);
1066
+ case commands.userContentLocale:
1067
+ return getUserContentLocale$2();
995
1068
  case commands.nativeUpload:
996
1069
  case commands.nativeShare:
997
1070
  return unSupported();
@@ -1014,7 +1087,6 @@
1014
1087
  // send this to call a function in the frontend
1015
1088
  ERROR: 'ERROR' // receive this when something goes wrong
1016
1089
  };
1017
-
1018
1090
  const invocationMapping = {
1019
1091
  [commands.openLink]: 'openLink',
1020
1092
  [commands.nativeUpload]: 'nativeFileUpload',
@@ -1077,11 +1149,9 @@
1077
1149
  *
1078
1150
  * @param {string} id of the promise
1079
1151
  * @param {any} msg the message which will will be passed to resolve
1080
- *
1081
- * @throws {Error} on unknown id
1082
1152
  */
1083
1153
  const resolve = (id, msg) => {
1084
- if (!(id in promiseMap)) throw new Error('Tried to resolve an unknown [' + id + '] promise.');
1154
+ if (!(id in promiseMap)) return;
1085
1155
  promiseMap[id].resolve(msg);
1086
1156
  delete promiseMap[id];
1087
1157
  };
@@ -1091,10 +1161,9 @@
1091
1161
  *
1092
1162
  * @param {string} id of the promise
1093
1163
  * @param {any} err the error which will will be passed to reject
1094
- * @throws {Error} on unknown id
1095
1164
  */
1096
1165
  const reject = (id, err) => {
1097
- if (!(id in promiseMap)) throw new Error('Tried to reject an unknown [' + id + '] promise.');
1166
+ if (!(id in promiseMap)) return;
1098
1167
  promiseMap[id].reject(err);
1099
1168
  delete promiseMap[id];
1100
1169
  };
@@ -1129,7 +1198,7 @@
1129
1198
  * @static
1130
1199
  * @return {StaticValueStore}
1131
1200
  */
1132
- const dataStore$1 = _ref => {
1201
+ const dataStore = _ref => {
1133
1202
  let {
1134
1203
  platform,
1135
1204
  language
@@ -1144,26 +1213,53 @@
1144
1213
  branchDefaultLanguage: language.branchDefaultLanguage
1145
1214
  };
1146
1215
  };
1147
- let connection$1 = null;
1216
+ let connection = null;
1148
1217
  const targetOrigin = '*';
1149
1218
 
1150
1219
  /**
1151
1220
  * Connect to the Staffbase App.
1152
1221
  *
1153
- * Create a connection to a Staffbase app 3.6
1154
- * @return {Promise<function>} An appropriate send function
1222
+ * Create a connection to a Staffbase app
1223
+ * Tries to reconnect until an answer is received
1224
+ *
1225
+ * @return {Promise<Function>} An appropriate send function
1155
1226
  */
1156
- const connect$2 = () => {
1157
- if (connection$1) {
1158
- return connection$1;
1227
+ const connect$1 = () => {
1228
+ if (connection) {
1229
+ return connection;
1159
1230
  }
1160
1231
  const connectId = create();
1161
- connection$1 = get(connectId).then(function (payload) {
1162
- return sendMessage$2(dataStore$1(payload));
1232
+ let timeout;
1233
+ const delayFactor = 1.2;
1234
+ connection = get(connectId).then(payload => {
1235
+ window.clearTimeout(timeout);
1236
+ return sendMessage$1(dataStore(payload));
1163
1237
  });
1164
1238
  window.addEventListener('message', receiveMessage);
1165
- window.parent.postMessage([protocol.HELLO, connectId, []], targetOrigin);
1166
- return connection$1;
1239
+ const recurringConnect = function () {
1240
+ let delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 500;
1241
+ timeout = window.setTimeout(() => {
1242
+ if (delay < 1200) {
1243
+ recurringConnect(delay * delayFactor);
1244
+ } else {
1245
+ reject(connectId, 'No answer from Staffbase App');
1246
+ disconnect();
1247
+ }
1248
+ }, delay);
1249
+ window.parent.postMessage([protocol.HELLO, connectId, []], targetOrigin);
1250
+ };
1251
+ recurringConnect();
1252
+ return connection;
1253
+ };
1254
+
1255
+ /**
1256
+ * Disconnect from the Staffbase App
1257
+ *
1258
+ * Only useful for tests.
1259
+ */
1260
+ const disconnect = () => {
1261
+ window.removeEventListener('message', receiveMessage);
1262
+ connection = null;
1167
1263
  };
1168
1264
 
1169
1265
  /**
@@ -1215,7 +1311,7 @@
1215
1311
  * @return {Promise<any>} which awaits the response of the Staffbase App
1216
1312
  * @throws {Error} on commands not supported by protocol
1217
1313
  */
1218
- const sendMessage$2 = store => async function (cmd) {
1314
+ const sendMessage$1 = store => async function (cmd) {
1219
1315
  switch (cmd) {
1220
1316
  case commands.version:
1221
1317
  case commands.native:
@@ -1232,7 +1328,7 @@
1232
1328
  for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1233
1329
  payload[_key - 1] = arguments[_key];
1234
1330
  }
1235
- return sendInvocationCall$1(create())(invocationMapping[cmd], payload);
1331
+ return sendInvocationCall(create())(invocationMapping[cmd], payload);
1236
1332
  default:
1237
1333
  throw new Error('Command ' + cmd + ' not supported by driver');
1238
1334
  }
@@ -1247,164 +1343,16 @@
1247
1343
  *
1248
1344
  * @return {Promise}
1249
1345
  */
1250
- const sendInvocationCall$1 = promiseID => (process, args) => {
1346
+ const sendInvocationCall = promiseID => (process, args) => {
1251
1347
  window.parent.postMessage([protocol.INVOCATION, promiseID, process, args], targetOrigin);
1252
1348
  return get(promiseID);
1253
1349
  };
1254
1350
 
1255
- let connection = null;
1256
- let outMsgQueue = [];
1257
-
1258
- /**
1259
- * Simple store solution to make the initial data available
1260
- * as static values
1261
- *
1262
- * @param {InitialValues} initial the initial data from the frontend
1263
- * @static
1264
- * @return {StaticValueStore}
1265
- */
1266
- const dataStore = _ref => {
1267
- let {
1268
- platform,
1269
- language
1270
- } = _ref;
1271
- return {
1272
- mobile: platform.mobile,
1273
- version: platform.version,
1274
- native: platform.native,
1275
- ios: platform.native === 'ios',
1276
- android: platform.native === 'android',
1277
- langInfos: language,
1278
- branchDefaultLang: language.branchDefaultLanguage
1279
- };
1280
- };
1281
- window.Staffbase = window.Staffbase || {};
1282
- window.Staffbase.plugins = {
1283
- getMessages: multiMessageProvider,
1284
- putMessage: singleMessageReceiver
1285
- };
1286
-
1287
- /**
1288
- * Connect to the Staffbase App.
1289
- *
1290
- * Create a connection to a Staffbase app 3.6 from a native tab
1291
- * @return {Promise<function>} An appropriate send function
1292
- */
1293
- const connect$1 = () => {
1294
- if (connection) {
1295
- return connection;
1296
- }
1297
- const connectId = create();
1298
- connection = get(connectId).then(function (payload) {
1299
- return sendMessage$1(dataStore(payload));
1300
- });
1301
- outMsgQueue.push([protocol.HELLO, connectId, []]);
1302
- return connection;
1303
- };
1304
-
1305
- /**
1306
- * A function which returns an array of messages
1307
- *
1308
- * The return value holds all messages in the order the were
1309
- * received over time by sendMessage
1310
- *
1311
- * @return {Array} ordered list of messages
1312
- */
1313
- function multiMessageProvider() {
1314
- const queueRef = outMsgQueue;
1315
- if (queueRef.length) ;
1316
- outMsgQueue = [];
1317
- return queueRef;
1318
- }
1319
-
1320
- /**
1321
- * A function which can receive a single message.
1322
- *
1323
- * Can be attached to window.onPostMessage
1324
- * @param {Array} msg Staffbase 3.6 message
1325
- */
1326
- function singleMessageReceiver(msg) {
1327
- let type;
1328
- let id;
1329
- let payload;
1330
-
1331
- // safe destructure
1332
- try {
1333
- [type, id, payload] = msg;
1334
- switch (type) {
1335
- case protocol.SUCCESS:
1336
- resolve(id, payload);
1337
- break;
1338
- case protocol.ERROR:
1339
- reject(id, payload);
1340
- break;
1341
- default:
1342
- // even thought catch-ignore is a bad style
1343
- // there may be other participants listening
1344
- // to messages in a different format so we
1345
- // silently ignore here
1346
- return;
1347
- }
1348
- } catch (e) {
1349
- // even thought catch-ignore is a bad style
1350
- // there may be other participants listening
1351
- // to messages in a different format so we
1352
- // silently ignore here
1353
- return;
1354
- }
1355
- }
1356
-
1357
- /**
1358
- * Send a SDK command to the Staffbase App.
1359
- *
1360
- * Translates SDK commands into protocol native commands.
1361
- * @param {StaticValueStore} store the store object
1362
- * @param {String} cmd an SDK command
1363
- * @param {array} payload for the command
1364
- * @return {Promise<any>} which awaits the response of the Staffbase App
1365
- * @throws {Error} on commands not supported by protocol
1366
- */
1367
- const sendMessage$1 = store => async function (cmd) {
1368
- switch (cmd) {
1369
- case commands.version:
1370
- case commands.native:
1371
- case commands.mobile:
1372
- case commands.ios:
1373
- case commands.android:
1374
- case commands.langInfos:
1375
- case commands.branchDefaultLang:
1376
- return store[reversedCommands[cmd]];
1377
- case commands.openLink:
1378
- case commands.prefContentLang:
1379
- for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1380
- payload[_key - 1] = arguments[_key];
1381
- }
1382
- return sendInvocationCall(invocationMapping[cmd], payload);
1383
- default:
1384
- throw new Error('Command ' + cmd + ' not supported by driver');
1385
- }
1386
- };
1387
-
1388
- /**
1389
- * Create a promise and send an invocation call to the frontend
1390
- *
1391
- * @param {string} process the name of the process to call
1392
- * @param {array} args an array of arguments
1393
- *
1394
- * @return {Promise}
1395
- */
1396
- const sendInvocationCall = (process, args) => {
1397
- const promiseID = create();
1398
- outMsgQueue.push([protocol.INVOCATION, promiseID, process, args]);
1399
- return get(promiseID);
1400
- };
1401
-
1402
1351
  let connector;
1403
1352
  const connect = async () => {
1404
- const putMessageConnection = connect$1();
1405
- const postMessageConnection = connect$2();
1353
+ const postMessageConnection = connect$1();
1406
1354
  const fallbackConnection = fallback();
1407
- const realConnectionBucket = [putMessageConnection, postMessageConnection];
1355
+ const realConnectionBucket = [postMessageConnection];
1408
1356
  const fallbackConnectionBucket = realConnectionBucket.concat(fallbackConnection);
1409
1357
 
1410
1358
  // Wait on the real communication and replace the connector with
@@ -1574,6 +1522,15 @@
1574
1522
  return sendMessage(commands.prefContentLang, content);
1575
1523
  };
1576
1524
 
1525
+ /**
1526
+ * Get the default content language configured for the branch.
1527
+ *
1528
+ * @return {Promise<Object>}
1529
+ */
1530
+ const getUserContentLocale$1 = async () => {
1531
+ return sendMessage(commands.langInfos).then(res => res.userContentLocale);
1532
+ };
1533
+
1577
1534
  /**
1578
1535
  * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.
1579
1536
  * This library supports the full semver specification, including comparing versions with different number of digits like `1.0.0`, `1.0`, `1`, and pre-release versions like `1.0.0-alpha`.
@@ -1673,6 +1630,7 @@
1673
1630
  * Interface exports
1674
1631
  */
1675
1632
 
1633
+
1676
1634
  /**
1677
1635
  * Check if device is able to perform a download.
1678
1636
  * @function
@@ -1779,6 +1737,13 @@
1779
1737
  */
1780
1738
  const getPreferredContentLocale = async content => getPreferredContentLocale$1(content);
1781
1739
 
1740
+ /**
1741
+ * Get the current user's content locale, fallback to branch default locale
1742
+ * @function
1743
+ * @return {Promise<any>}
1744
+ */
1745
+ const getUserContentLocale = async () => getUserContentLocale$1();
1746
+
1782
1747
  /**
1783
1748
  * Open a share dialog on native devices
1784
1749
  *
@@ -1803,6 +1768,7 @@
1803
1768
  exports.getBranchLanguages = getBranchLanguages;
1804
1769
  exports.getContentLanguages = getContentLanguages;
1805
1770
  exports.getPreferredContentLocale = getPreferredContentLocale;
1771
+ exports.getUserContentLocale = getUserContentLocale;
1806
1772
  exports.isAndroidDevice = isAndroidDevice;
1807
1773
  exports.isIosDevice = isIosDevice;
1808
1774
  exports.isMobileApp = isMobileApp;