@staffbase/plugins-client-sdk 2.0.1 → 3.0.0-beta.4

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 2024
11
11
  * @license Apache-2.0
12
12
  */
13
13
 
@@ -40,6 +40,8 @@ var loglevel = {
40
40
  var undefinedType = "undefined";
41
41
  var isIE = typeof window !== undefinedType && typeof window.navigator !== undefinedType && /Trident\/|MSIE /.test(window.navigator.userAgent);
42
42
  var logMethods = ["trace", "debug", "info", "warn", "error"];
43
+ var _loggersByName = {};
44
+ var defaultLogger = null;
43
45
 
44
46
  // Cross-browser bind equivalent that works at least back to IE6
45
47
  function bindMethod(obj, methodName) {
@@ -92,23 +94,31 @@ var loglevel = {
92
94
 
93
95
  // These private functions always need `this` to be set properly
94
96
 
95
- function replaceLoggingMethods(level, loggerName) {
97
+ function replaceLoggingMethods() {
96
98
  /*jshint validthis:true */
99
+ var level = this.getLevel();
100
+
101
+ // Replace the actual methods.
97
102
  for (var i = 0; i < logMethods.length; i++) {
98
103
  var methodName = logMethods[i];
99
- this[methodName] = i < level ? noop : this.methodFactory(methodName, level, loggerName);
104
+ this[methodName] = i < level ? noop : this.methodFactory(methodName, level, this.name);
100
105
  }
101
106
 
102
107
  // Define log.log as an alias for log.debug
103
108
  this.log = this.debug;
109
+
110
+ // Return any important warnings.
111
+ if (typeof console === undefinedType && level < this.levels.SILENT) {
112
+ return "No console available for logging";
113
+ }
104
114
  }
105
115
 
106
116
  // In old IE versions, the console isn't present until you first open it.
107
117
  // We build realMethod() replacements here that regenerate logging methods
108
- function enableLoggingWhenConsoleArrives(methodName, level, loggerName) {
118
+ function enableLoggingWhenConsoleArrives(methodName) {
109
119
  return function () {
110
120
  if (typeof console !== undefinedType) {
111
- replaceLoggingMethods.call(this, level, loggerName);
121
+ replaceLoggingMethods.call(this);
112
122
  this[methodName].apply(this, arguments);
113
123
  }
114
124
  };
@@ -116,14 +126,34 @@ var loglevel = {
116
126
 
117
127
  // By default, we use closely bound real methods wherever possible, and
118
128
  // otherwise we wait for a console to appear, and then try again.
119
- function defaultMethodFactory(methodName, level, loggerName) {
129
+ function defaultMethodFactory(methodName, _level, _loggerName) {
120
130
  /*jshint validthis:true */
121
131
  return realMethod(methodName) || enableLoggingWhenConsoleArrives.apply(this, arguments);
122
132
  }
123
- function Logger(name, defaultLevel, factory) {
133
+ function Logger(name, factory) {
134
+ // Private instance variables.
124
135
  var self = this;
125
- var currentLevel;
126
- defaultLevel = defaultLevel == null ? "WARN" : defaultLevel;
136
+ /**
137
+ * The level inherited from a parent logger (or a global default). We
138
+ * cache this here rather than delegating to the parent so that it stays
139
+ * in sync with the actual logging methods that we have installed (the
140
+ * parent could change levels but we might not have rebuilt the loggers
141
+ * in this child yet).
142
+ * @type {number}
143
+ */
144
+ var inheritedLevel;
145
+ /**
146
+ * The default level for this logger, if any. If set, this overrides
147
+ * `inheritedLevel`.
148
+ * @type {number|null}
149
+ */
150
+ var defaultLevel;
151
+ /**
152
+ * A user-specific level for this logger. If set, this overrides
153
+ * `defaultLevel`.
154
+ * @type {number|null}
155
+ */
156
+ var userLevel;
127
157
  var storageKey = "loglevel";
128
158
  if (typeof name === "string") {
129
159
  storageKey += ":" + name;
@@ -156,9 +186,10 @@ var loglevel = {
156
186
  if (typeof storedLevel === undefinedType) {
157
187
  try {
158
188
  var cookie = window.document.cookie;
159
- var location = cookie.indexOf(encodeURIComponent(storageKey) + "=");
189
+ var cookieName = encodeURIComponent(storageKey);
190
+ var location = cookie.indexOf(cookieName + "=");
160
191
  if (location !== -1) {
161
- storedLevel = /^([^;]+)/.exec(cookie.slice(location))[1];
192
+ storedLevel = /^([^;]+)/.exec(cookie.slice(location + cookieName.length + 1))[1];
162
193
  }
163
194
  } catch (ignore) {}
164
195
  }
@@ -175,7 +206,6 @@ var loglevel = {
175
206
  // Use localStorage if available
176
207
  try {
177
208
  window.localStorage.removeItem(storageKey);
178
- return;
179
209
  } catch (ignore) {}
180
210
 
181
211
  // Use session cookie as fallback
@@ -183,6 +213,17 @@ var loglevel = {
183
213
  window.document.cookie = encodeURIComponent(storageKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 UTC";
184
214
  } catch (ignore) {}
185
215
  }
216
+ function normalizeLevel(input) {
217
+ var level = input;
218
+ if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
219
+ level = self.levels[level.toUpperCase()];
220
+ }
221
+ if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
222
+ return level;
223
+ } else {
224
+ throw new TypeError("log.setLevel() called with invalid level: " + input);
225
+ }
226
+ }
186
227
 
187
228
  /*
188
229
  *
@@ -201,46 +242,60 @@ var loglevel = {
201
242
  };
202
243
  self.methodFactory = factory || defaultMethodFactory;
203
244
  self.getLevel = function () {
204
- return currentLevel;
245
+ if (userLevel != null) {
246
+ return userLevel;
247
+ } else if (defaultLevel != null) {
248
+ return defaultLevel;
249
+ } else {
250
+ return inheritedLevel;
251
+ }
205
252
  };
206
253
  self.setLevel = function (level, persist) {
207
- if (typeof level === "string" && self.levels[level.toUpperCase()] !== undefined) {
208
- level = self.levels[level.toUpperCase()];
209
- }
210
- if (typeof level === "number" && level >= 0 && level <= self.levels.SILENT) {
211
- currentLevel = level;
212
- if (persist !== false) {
213
- // defaults to true
214
- persistLevelIfPossible(level);
215
- }
216
- replaceLoggingMethods.call(self, level, name);
217
- if (typeof console === undefinedType && level < self.levels.SILENT) {
218
- return "No console available for logging";
219
- }
220
- } else {
221
- throw "log.setLevel() called with invalid level: " + level;
254
+ userLevel = normalizeLevel(level);
255
+ if (persist !== false) {
256
+ // defaults to true
257
+ persistLevelIfPossible(userLevel);
222
258
  }
259
+
260
+ // NOTE: in v2, this should call rebuild(), which updates children.
261
+ return replaceLoggingMethods.call(self);
223
262
  };
224
263
  self.setDefaultLevel = function (level) {
225
- defaultLevel = level;
264
+ defaultLevel = normalizeLevel(level);
226
265
  if (!getPersistedLevel()) {
227
266
  self.setLevel(level, false);
228
267
  }
229
268
  };
230
269
  self.resetLevel = function () {
231
- self.setLevel(defaultLevel, false);
270
+ userLevel = null;
232
271
  clearPersistedLevel();
272
+ replaceLoggingMethods.call(self);
273
+ };
274
+ self.enableAll = function (persist) {
275
+ self.setLevel(self.levels.TRACE, persist);
233
276
  };
234
277
  self.disableAll = function (persist) {
235
278
  self.setLevel(self.levels.SILENT, persist);
236
279
  };
280
+ self.rebuild = function () {
281
+ if (defaultLogger !== self) {
282
+ inheritedLevel = normalizeLevel(defaultLogger.getLevel());
283
+ }
284
+ replaceLoggingMethods.call(self);
285
+ if (defaultLogger === self) {
286
+ for (var childName in _loggersByName) {
287
+ _loggersByName[childName].rebuild();
288
+ }
289
+ }
290
+ };
237
291
 
238
- // Initialize with the right level
292
+ // Initialize all the internal levels.
293
+ inheritedLevel = normalizeLevel(defaultLogger ? defaultLogger.getLevel() : "WARN");
239
294
  var initialLevel = getPersistedLevel();
240
- if (initialLevel == null) {
241
- initialLevel = defaultLevel;
295
+ if (initialLevel != null) {
296
+ userLevel = normalizeLevel(initialLevel);
242
297
  }
243
- self.setLevel(initialLevel, false);
298
+ replaceLoggingMethods.call(self);
244
299
  }
245
300
 
246
301
  /*
@@ -249,15 +304,14 @@ var loglevel = {
249
304
  *
250
305
  */
251
306
 
252
- var defaultLogger = new Logger();
253
- var _loggersByName = {};
307
+ defaultLogger = new Logger();
254
308
  defaultLogger.getLogger = function getLogger(name) {
255
309
  if (typeof name !== "symbol" && typeof name !== "string" || name === "") {
256
310
  throw new TypeError("You must supply a name when creating a logger.");
257
311
  }
258
312
  var logger = _loggersByName[name];
259
313
  if (!logger) {
260
- logger = _loggersByName[name] = new Logger(name, defaultLogger.getLevel(), defaultLogger.methodFactory);
314
+ logger = _loggersByName[name] = new Logger(name, defaultLogger.methodFactory);
261
315
  }
262
316
  return logger;
263
317
  };
@@ -343,7 +397,8 @@ const commands = {
343
397
  nativeShare: 'nativeShareDialog',
344
398
  langInfos: 'getLanguageInfos',
345
399
  branchDefaultLang: 'getBranchDefaultLanguage',
346
- prefContentLang: 'getPreferredContentLocale'
400
+ prefContentLang: 'getPreferredContentLocale',
401
+ userContentLocale: 'getUserContentLocale'
347
402
  };
348
403
 
349
404
  /**
@@ -932,7 +987,17 @@ const getPreferredContentLocale$2 = content => {
932
987
  }
933
988
  };
934
989
 
935
- let connection$2 = null;
990
+ /**
991
+ * Get the current user's content locale, fallback to branch default locale
992
+ *
993
+ * @return {String} the user's content locale
994
+ */
995
+ const getUserContentLocale$2 = () => {
996
+ const locale = getBranchDefaultLanguage$2().locale;
997
+ return locale;
998
+ };
999
+
1000
+ let connection$1 = null;
936
1001
  const fallbackKickIn = 500;
937
1002
 
938
1003
  /**
@@ -943,15 +1008,15 @@ const fallbackKickIn = 500;
943
1008
  * @return {Promise<function>} An appropriate send function
944
1009
  */
945
1010
  var fallback = (() => {
946
- if (connection$2) {
947
- return connection$2;
1011
+ if (connection$1) {
1012
+ return connection$1;
948
1013
  }
949
- connection$2 = new Promise(resolve => {
1014
+ connection$1 = new Promise(resolve => {
950
1015
  setTimeout(function () {
951
- resolve(sendMessage$3);
1016
+ resolve(sendMessage$2);
952
1017
  }, fallbackKickIn);
953
1018
  });
954
- return connection$2;
1019
+ return connection$1;
955
1020
  });
956
1021
 
957
1022
  /**
@@ -963,7 +1028,7 @@ var fallback = (() => {
963
1028
  * @return {Promise<any>} which awaits the response of the Staffbase App
964
1029
  * @throws {Error} on commands not supported by protocol
965
1030
  */
966
- const sendMessage$3 = async function (cmd) {
1031
+ const sendMessage$2 = async function (cmd) {
967
1032
  for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
968
1033
  payload[_key - 1] = arguments[_key];
969
1034
  }
@@ -986,6 +1051,8 @@ const sendMessage$3 = async function (cmd) {
986
1051
  return getBranchDefaultLanguage$2();
987
1052
  case commands.prefContentLang:
988
1053
  return getPreferredContentLocale$2.apply(null, payload);
1054
+ case commands.userContentLocale:
1055
+ return getUserContentLocale$2();
989
1056
  case commands.nativeUpload:
990
1057
  case commands.nativeShare:
991
1058
  return unSupported();
@@ -1008,7 +1075,6 @@ var protocol = {
1008
1075
  // send this to call a function in the frontend
1009
1076
  ERROR: 'ERROR' // receive this when something goes wrong
1010
1077
  };
1011
-
1012
1078
  const invocationMapping = {
1013
1079
  [commands.openLink]: 'openLink',
1014
1080
  [commands.nativeUpload]: 'nativeFileUpload',
@@ -1071,11 +1137,9 @@ const create = () => {
1071
1137
  *
1072
1138
  * @param {string} id of the promise
1073
1139
  * @param {any} msg the message which will will be passed to resolve
1074
- *
1075
- * @throws {Error} on unknown id
1076
1140
  */
1077
1141
  const resolve = (id, msg) => {
1078
- if (!(id in promiseMap)) throw new Error('Tried to resolve an unknown [' + id + '] promise.');
1142
+ if (!(id in promiseMap)) return;
1079
1143
  promiseMap[id].resolve(msg);
1080
1144
  delete promiseMap[id];
1081
1145
  };
@@ -1085,10 +1149,9 @@ const resolve = (id, msg) => {
1085
1149
  *
1086
1150
  * @param {string} id of the promise
1087
1151
  * @param {any} err the error which will will be passed to reject
1088
- * @throws {Error} on unknown id
1089
1152
  */
1090
1153
  const reject = (id, err) => {
1091
- if (!(id in promiseMap)) throw new Error('Tried to reject an unknown [' + id + '] promise.');
1154
+ if (!(id in promiseMap)) return;
1092
1155
  promiseMap[id].reject(err);
1093
1156
  delete promiseMap[id];
1094
1157
  };
@@ -1123,7 +1186,7 @@ const get = id => {
1123
1186
  * @static
1124
1187
  * @return {StaticValueStore}
1125
1188
  */
1126
- const dataStore$1 = _ref => {
1189
+ const dataStore = _ref => {
1127
1190
  let {
1128
1191
  platform,
1129
1192
  language
@@ -1138,26 +1201,53 @@ const dataStore$1 = _ref => {
1138
1201
  branchDefaultLanguage: language.branchDefaultLanguage
1139
1202
  };
1140
1203
  };
1141
- let connection$1 = null;
1204
+ let connection = null;
1142
1205
  const targetOrigin = '*';
1143
1206
 
1144
1207
  /**
1145
1208
  * Connect to the Staffbase App.
1146
1209
  *
1147
- * Create a connection to a Staffbase app 3.6
1148
- * @return {Promise<function>} An appropriate send function
1210
+ * Create a connection to a Staffbase app
1211
+ * Tries to reconnect until an answer is received
1212
+ *
1213
+ * @return {Promise<Function>} An appropriate send function
1149
1214
  */
1150
- const connect$2 = () => {
1151
- if (connection$1) {
1152
- return connection$1;
1215
+ const connect$1 = () => {
1216
+ if (connection) {
1217
+ return connection;
1153
1218
  }
1154
1219
  const connectId = create();
1155
- connection$1 = get(connectId).then(function (payload) {
1156
- return sendMessage$2(dataStore$1(payload));
1220
+ let timeout;
1221
+ const delayFactor = 1.2;
1222
+ connection = get(connectId).then(payload => {
1223
+ window.clearTimeout(timeout);
1224
+ return sendMessage$1(dataStore(payload));
1157
1225
  });
1158
1226
  window.addEventListener('message', receiveMessage);
1159
- window.parent.postMessage([protocol.HELLO, connectId, []], targetOrigin);
1160
- return connection$1;
1227
+ const recurringConnect = function () {
1228
+ let delay = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 500;
1229
+ timeout = window.setTimeout(() => {
1230
+ if (delay < 1200) {
1231
+ recurringConnect(delay * delayFactor);
1232
+ } else {
1233
+ reject(connectId, 'No answer from Staffbase App');
1234
+ disconnect();
1235
+ }
1236
+ }, delay);
1237
+ window.parent.postMessage([protocol.HELLO, connectId, []], targetOrigin);
1238
+ };
1239
+ recurringConnect();
1240
+ return connection;
1241
+ };
1242
+
1243
+ /**
1244
+ * Disconnect from the Staffbase App
1245
+ *
1246
+ * Only useful for tests.
1247
+ */
1248
+ const disconnect = () => {
1249
+ window.removeEventListener('message', receiveMessage);
1250
+ connection = null;
1161
1251
  };
1162
1252
 
1163
1253
  /**
@@ -1209,7 +1299,7 @@ const receiveMessage = async evt => {
1209
1299
  * @return {Promise<any>} which awaits the response of the Staffbase App
1210
1300
  * @throws {Error} on commands not supported by protocol
1211
1301
  */
1212
- const sendMessage$2 = store => async function (cmd) {
1302
+ const sendMessage$1 = store => async function (cmd) {
1213
1303
  switch (cmd) {
1214
1304
  case commands.version:
1215
1305
  case commands.native:
@@ -1226,7 +1316,7 @@ const sendMessage$2 = store => async function (cmd) {
1226
1316
  for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1227
1317
  payload[_key - 1] = arguments[_key];
1228
1318
  }
1229
- return sendInvocationCall$1(create())(invocationMapping[cmd], payload);
1319
+ return sendInvocationCall(create())(invocationMapping[cmd], payload);
1230
1320
  default:
1231
1321
  throw new Error('Command ' + cmd + ' not supported by driver');
1232
1322
  }
@@ -1241,164 +1331,16 @@ const sendMessage$2 = store => async function (cmd) {
1241
1331
  *
1242
1332
  * @return {Promise}
1243
1333
  */
1244
- const sendInvocationCall$1 = promiseID => (process, args) => {
1334
+ const sendInvocationCall = promiseID => (process, args) => {
1245
1335
  window.parent.postMessage([protocol.INVOCATION, promiseID, process, args], targetOrigin);
1246
1336
  return get(promiseID);
1247
1337
  };
1248
1338
 
1249
- let connection = null;
1250
- let outMsgQueue = [];
1251
-
1252
- /**
1253
- * Simple store solution to make the initial data available
1254
- * as static values
1255
- *
1256
- * @param {InitialValues} initial the initial data from the frontend
1257
- * @static
1258
- * @return {StaticValueStore}
1259
- */
1260
- const dataStore = _ref => {
1261
- let {
1262
- platform,
1263
- language
1264
- } = _ref;
1265
- return {
1266
- mobile: platform.mobile,
1267
- version: platform.version,
1268
- native: platform.native,
1269
- ios: platform.native === 'ios',
1270
- android: platform.native === 'android',
1271
- langInfos: language,
1272
- branchDefaultLang: language.branchDefaultLanguage
1273
- };
1274
- };
1275
- window.Staffbase = window.Staffbase || {};
1276
- window.Staffbase.plugins = {
1277
- getMessages: multiMessageProvider,
1278
- putMessage: singleMessageReceiver
1279
- };
1280
-
1281
- /**
1282
- * Connect to the Staffbase App.
1283
- *
1284
- * Create a connection to a Staffbase app 3.6 from a native tab
1285
- * @return {Promise<function>} An appropriate send function
1286
- */
1287
- const connect$1 = () => {
1288
- if (connection) {
1289
- return connection;
1290
- }
1291
- const connectId = create();
1292
- connection = get(connectId).then(function (payload) {
1293
- return sendMessage$1(dataStore(payload));
1294
- });
1295
- outMsgQueue.push([protocol.HELLO, connectId, []]);
1296
- return connection;
1297
- };
1298
-
1299
- /**
1300
- * A function which returns an array of messages
1301
- *
1302
- * The return value holds all messages in the order the were
1303
- * received over time by sendMessage
1304
- *
1305
- * @return {Array} ordered list of messages
1306
- */
1307
- function multiMessageProvider() {
1308
- const queueRef = outMsgQueue;
1309
- if (queueRef.length) ;
1310
- outMsgQueue = [];
1311
- return queueRef;
1312
- }
1313
-
1314
- /**
1315
- * A function which can receive a single message.
1316
- *
1317
- * Can be attached to window.onPostMessage
1318
- * @param {Array} msg Staffbase 3.6 message
1319
- */
1320
- function singleMessageReceiver(msg) {
1321
- let type;
1322
- let id;
1323
- let payload;
1324
-
1325
- // safe destructure
1326
- try {
1327
- [type, id, payload] = msg;
1328
- switch (type) {
1329
- case protocol.SUCCESS:
1330
- resolve(id, payload);
1331
- break;
1332
- case protocol.ERROR:
1333
- reject(id, payload);
1334
- break;
1335
- default:
1336
- // even thought catch-ignore is a bad style
1337
- // there may be other participants listening
1338
- // to messages in a different format so we
1339
- // silently ignore here
1340
- return;
1341
- }
1342
- } catch (e) {
1343
- // even thought catch-ignore is a bad style
1344
- // there may be other participants listening
1345
- // to messages in a different format so we
1346
- // silently ignore here
1347
- return;
1348
- }
1349
- }
1350
-
1351
- /**
1352
- * Send a SDK command to the Staffbase App.
1353
- *
1354
- * Translates SDK commands into protocol native commands.
1355
- * @param {StaticValueStore} store the store object
1356
- * @param {String} cmd an SDK command
1357
- * @param {array} payload for the command
1358
- * @return {Promise<any>} which awaits the response of the Staffbase App
1359
- * @throws {Error} on commands not supported by protocol
1360
- */
1361
- const sendMessage$1 = store => async function (cmd) {
1362
- switch (cmd) {
1363
- case commands.version:
1364
- case commands.native:
1365
- case commands.mobile:
1366
- case commands.ios:
1367
- case commands.android:
1368
- case commands.langInfos:
1369
- case commands.branchDefaultLang:
1370
- return store[reversedCommands[cmd]];
1371
- case commands.openLink:
1372
- case commands.prefContentLang:
1373
- for (var _len = arguments.length, payload = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
1374
- payload[_key - 1] = arguments[_key];
1375
- }
1376
- return sendInvocationCall(invocationMapping[cmd], payload);
1377
- default:
1378
- throw new Error('Command ' + cmd + ' not supported by driver');
1379
- }
1380
- };
1381
-
1382
- /**
1383
- * Create a promise and send an invocation call to the frontend
1384
- *
1385
- * @param {string} process the name of the process to call
1386
- * @param {array} args an array of arguments
1387
- *
1388
- * @return {Promise}
1389
- */
1390
- const sendInvocationCall = (process, args) => {
1391
- const promiseID = create();
1392
- outMsgQueue.push([protocol.INVOCATION, promiseID, process, args]);
1393
- return get(promiseID);
1394
- };
1395
-
1396
1339
  let connector;
1397
1340
  const connect = async () => {
1398
- const putMessageConnection = connect$1();
1399
- const postMessageConnection = connect$2();
1341
+ const postMessageConnection = connect$1();
1400
1342
  const fallbackConnection = fallback();
1401
- const realConnectionBucket = [putMessageConnection, postMessageConnection];
1343
+ const realConnectionBucket = [postMessageConnection];
1402
1344
  const fallbackConnectionBucket = realConnectionBucket.concat(fallbackConnection);
1403
1345
 
1404
1346
  // Wait on the real communication and replace the connector with
@@ -1568,6 +1510,15 @@ const getPreferredContentLocale$1 = async content => {
1568
1510
  return sendMessage(commands.prefContentLang, content);
1569
1511
  };
1570
1512
 
1513
+ /**
1514
+ * Get the default content language configured for the branch.
1515
+ *
1516
+ * @return {Promise<Object>}
1517
+ */
1518
+ const getUserContentLocale$1 = async () => {
1519
+ return sendMessage(commands.langInfos).then(res => res.userContentLocale);
1520
+ };
1521
+
1571
1522
  /**
1572
1523
  * Compare [semver](https://semver.org/) version strings to find greater, equal or lesser.
1573
1524
  * 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`.
@@ -1667,6 +1618,7 @@ const canDownload = async () => {
1667
1618
  * Interface exports
1668
1619
  */
1669
1620
 
1621
+
1670
1622
  /**
1671
1623
  * Check if device is able to perform a download.
1672
1624
  * @function
@@ -1773,6 +1725,13 @@ const getContentLanguages = async () => getContentLanguages$1();
1773
1725
  */
1774
1726
  const getPreferredContentLocale = async content => getPreferredContentLocale$1(content);
1775
1727
 
1728
+ /**
1729
+ * Get the current user's content locale, fallback to branch default locale
1730
+ * @function
1731
+ * @return {Promise<any>}
1732
+ */
1733
+ const getUserContentLocale = async () => getUserContentLocale$1();
1734
+
1776
1735
  /**
1777
1736
  * Open a share dialog on native devices
1778
1737
  *
@@ -1791,5 +1750,5 @@ const getPreferredContentLocale = async content => getPreferredContentLocale$1(c
1791
1750
  const openNativeShareDialog = async content => openNativeShareDialog$1(content);
1792
1751
  /* experimental */
1793
1752
 
1794
- export { deviceCanDownload, getAppVersion, getBranchDefaultLanguage, getBranchLanguages, getContentLanguages, getPreferredContentLocale, isAndroidDevice, isIosDevice, isMobileApp, isNativeApp, openLink, openLinkExternal, openLinkInternal, openNativeFileDialog, openNativeShareDialog };
1753
+ export { deviceCanDownload, getAppVersion, getBranchDefaultLanguage, getBranchLanguages, getContentLanguages, getPreferredContentLocale, getUserContentLocale, isAndroidDevice, isIosDevice, isMobileApp, isNativeApp, openLink, openLinkExternal, openLinkInternal, openNativeFileDialog, openNativeShareDialog };
1795
1754
  //# sourceMappingURL=plugins-client-sdk.esm.js.map