swell-js 5.9.0 → 5.9.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.
package/dist/swell.cjs CHANGED
@@ -1,9 +1,128 @@
1
1
  'use strict';
2
2
 
3
- const qs = require('qs');
4
3
  const deepmerge = require('deepmerge');
5
4
  const fastCase = require('fast-case');
6
5
 
6
+ /*!
7
+ * The UTF-8/RFC 3986 encoder in this file is adapted from qs 6.16.0 (lib/utils.js).
8
+ * That code was originally written by Brian White (mscdex) for the io.js core
9
+ * querystring library and adapted by qs for stricter adherence to RFC 3986.
10
+ *
11
+ * @license BSD-3-Clause
12
+ *
13
+ * Copyright (c) 2014, Nathan LaFreniere and other contributors
14
+ * (https://github.com/ljharb/qs/graphs/contributors)
15
+ * All rights reserved.
16
+ *
17
+ * Redistribution and use in source and binary forms, with or without
18
+ * modification, are permitted provided that the following conditions are met:
19
+ *
20
+ * 1. Redistributions of source code must retain the above copyright notice, this
21
+ * list of conditions and the following disclaimer.
22
+ *
23
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
24
+ * this list of conditions and the following disclaimer in the documentation
25
+ * and/or other materials provided with the distribution.
26
+ *
27
+ * 3. Neither the name of the copyright holder nor the names of its
28
+ * contributors may be used to endorse or promote products derived from
29
+ * this software without specific prior written permission.
30
+ *
31
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
32
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
33
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
34
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
35
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
37
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
38
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
39
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
40
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41
+ */
42
+
43
+ const hex = Array.from({ length: 256 }, (_, c) =>
44
+ `%${c.toString(16).padStart(2, '0')}`.toUpperCase(),
45
+ );
46
+ const toISO = Date.prototype.toISOString;
47
+
48
+ function encode(value) {
49
+ if (value.length === 0) return value;
50
+ const string =
51
+ typeof value === 'symbol'
52
+ ? Symbol.prototype.toString.call(value)
53
+ : String(value);
54
+ let out = '';
55
+ for (let j = 0; j < string.length; j += 1024) {
56
+ let segment = string.slice(j, j + 1024);
57
+ if (j + 1024 < string.length) {
58
+ const last = segment.charCodeAt(segment.length - 1);
59
+ if (last >= 0xd800 && last <= 0xdbff) {
60
+ segment = segment.slice(0, -1);
61
+ j -= 1;
62
+ }
63
+ }
64
+ for (let i = 0; i < segment.length; ++i) {
65
+ let c = segment.charCodeAt(i);
66
+ if (
67
+ c === 0x2d ||
68
+ c === 0x2e ||
69
+ c === 0x5f ||
70
+ c === 0x7e ||
71
+ (c >= 0x30 && c <= 0x39) ||
72
+ (c >= 0x41 && c <= 0x5a) ||
73
+ (c >= 0x61 && c <= 0x7a)
74
+ ) {
75
+ out += segment.charAt(i);
76
+ } else if (c < 0x80) {
77
+ out += hex[c];
78
+ } else if (c < 0x800) {
79
+ out += hex[0xc0 | (c >> 6)] + hex[0x80 | (c & 0x3f)];
80
+ } else if (c < 0xd800 || c >= 0xe000) {
81
+ out +=
82
+ hex[0xe0 | (c >> 12)] +
83
+ hex[0x80 | ((c >> 6) & 0x3f)] +
84
+ hex[0x80 | (c & 0x3f)];
85
+ } else {
86
+ i += 1;
87
+ c = 0x10000 + (((c & 0x3ff) << 10) | (segment.charCodeAt(i) & 0x3ff));
88
+ out +=
89
+ hex[0xf0 | (c >> 18)] +
90
+ hex[0x80 | ((c >> 12) & 0x3f)] +
91
+ hex[0x80 | ((c >> 6) & 0x3f)] +
92
+ hex[0x80 | (c & 0x3f)];
93
+ }
94
+ }
95
+ }
96
+ return out;
97
+ }
98
+
99
+ function stringifyQuery(obj) {
100
+ if (typeof obj !== 'object' || obj === null) return '';
101
+ const parts = [];
102
+ const ancestors = new Set();
103
+ function walk(value, prefix) {
104
+ if (value === undefined) return;
105
+ if (value instanceof Date) value = toISO.call(value);
106
+ if (value === null) value = '';
107
+ const isObject = typeof value === 'object';
108
+ const isBuffer =
109
+ isObject &&
110
+ value.constructor &&
111
+ value.constructor.isBuffer &&
112
+ value.constructor.isBuffer(value);
113
+ if ((!isObject && typeof value !== 'function') || isBuffer) {
114
+ parts.push(`${encode(prefix)}=${encode(value)}`);
115
+ return;
116
+ }
117
+ if (ancestors.has(value)) throw new RangeError('Cyclic object value');
118
+ ancestors.add(value);
119
+ for (const key of Object.keys(value)) walk(value[key], `${prefix}[${key}]`);
120
+ ancestors.delete(value);
121
+ }
122
+ for (const key of Object.keys(obj)) walk(obj[key], key);
123
+ return parts.join('&');
124
+ }
125
+
7
126
  /** Detect free variable `global` from Node.js. */
8
127
  var freeGlobal = typeof global == 'object' && global && global.Object === Object && global;
9
128
 
@@ -4573,10 +4692,6 @@ function trimEnd(str) {
4573
4692
  return typeof str === 'string' ? str.replace(/[/]+$/, '') : '';
4574
4693
  }
4575
4694
 
4576
- function stringifyQuery(str) {
4577
- return qs.stringify(str);
4578
- }
4579
-
4580
4695
  function map(arr, cb) {
4581
4696
  return arr instanceof Array ? arr.map(cb) : [];
4582
4697
  }
@@ -12922,7 +13037,30 @@ function methods$2(api, opt) {
12922
13037
 
12923
13038
  const FORMATTERS = {};
12924
13039
 
13040
+ // A currency code is three letters. Anything else, such as a pending settings
13041
+ // Promise that was stringified to "[object Promise]", is not a currency.
13042
+ function isCurrencyCode(value) {
13043
+ return typeof value === 'string' && /^[a-z]{3}$/i.test(value);
13044
+ }
13045
+
13046
+ function defaultLocale() {
13047
+ return typeof navigator === 'object' ? navigator.language : 'en-US';
13048
+ }
13049
+
12925
13050
  function methods$1(api, opt) {
13051
+ // Reads a store setting without ever returning a Promise. Until settings
13052
+ // load, this starts the request and reports `loaded: false`.
13053
+ function readSetting(path, def) {
13054
+ const value = opt.api.settings.get(path, def);
13055
+
13056
+ if (value && typeof value.then === 'function') {
13057
+ value.catch(() => {}); // callers that await settings report the error
13058
+ return { loaded: false, value: def };
13059
+ }
13060
+
13061
+ return { loaded: true, value };
13062
+ }
13063
+
12926
13064
  return {
12927
13065
  code: null,
12928
13066
  state: null,
@@ -12940,52 +13078,72 @@ function methods$1(api, opt) {
12940
13078
 
12941
13079
  selected() {
12942
13080
  if (!this.code) {
12943
- this.set(
12944
- opt.getCookie('swell-currency') ||
12945
- opt.api.settings.get('store.currency'),
12946
- );
13081
+ const cookieCode = opt.getCookie('swell-currency');
13082
+
13083
+ if (isCurrencyCode(cookieCode)) {
13084
+ this.set(cookieCode);
13085
+ } else {
13086
+ const storeCode = readSetting('store.currency');
13087
+
13088
+ if (!storeCode.loaded) {
13089
+ // Settings are still loading: use a stand-in without saving it,
13090
+ // so the store currency is picked up once they arrive.
13091
+ return 'USD';
13092
+ }
13093
+
13094
+ this.set(isCurrencyCode(storeCode.value) ? storeCode.value : 'USD');
13095
+ }
12947
13096
  }
12948
13097
 
12949
13098
  return this.code;
12950
13099
  },
12951
13100
 
12952
13101
  get() {
12953
- if (!this.code) {
12954
- this.code = this.selected();
13102
+ const code = this.selected();
13103
+
13104
+ if (this.state) {
13105
+ return this.state;
12955
13106
  }
12956
- if (!this.state) {
12957
- this.state = this.set(this.code);
13107
+
13108
+ if (!readSetting('store.currencies').loaded) {
13109
+ // Not cached, so the currency's rate and decimals apply once
13110
+ // settings load.
13111
+ return { code };
12958
13112
  }
12959
- return this.state;
13113
+
13114
+ return this.set(code);
12960
13115
  },
12961
13116
 
12962
13117
  set(code = 'USD') {
12963
- this.code = code;
12964
- this.state = find$1(this.list(), { code }) || { code };
13118
+ if (!isCurrencyCode(code)) {
13119
+ // Never store or persist something that isn't a currency code.
13120
+ return this.state || { code: this.code || 'USD' };
13121
+ }
12965
13122
 
12966
- this.locale = String(
12967
- opt.api.settings.get(
12968
- 'store.locale',
12969
- typeof navigator === 'object' ? navigator.language : 'en-US',
12970
- ),
12971
- );
13123
+ const list = readSetting('store.currencies', []);
13124
+ const state = (list.loaded && find$1(list.value, { code })) || { code };
13125
+
13126
+ this.code = code;
13127
+ // Only cache a state built from the loaded currency list.
13128
+ this.state = list.loaded ? state : null;
13129
+ this.locale = String(readSetting('store.locale', defaultLocale()).value);
12972
13130
 
12973
13131
  opt.setCookie('swell-currency', code);
12974
13132
 
12975
- return this.state;
13133
+ return state;
12976
13134
  },
12977
13135
 
12978
13136
  format(amount, params = {}) {
12979
13137
  let state = this.get();
12980
13138
  if (params.code && params.code !== state.code) {
12981
- const list = this.list();
13139
+ const list = readSetting('store.currencies', []).value;
12982
13140
  state = find$1(list, { code: params.code }) || { code: params.code };
12983
13141
  }
12984
13142
 
12985
13143
  const { code = 'USD', type, decimals, rate } = state;
12986
13144
  const formatCode = params.code || code;
12987
13145
  const formatRate = params.rate || rate;
12988
- const formatLocale = params.locale || this.locale;
13146
+ const formatLocale = params.locale || this.locale || defaultLocale();
12989
13147
  const formatDecimals = 'decimals' in params ? params.decimals : decimals;
12990
13148
  const { convert = true } = params;
12991
13149
 
@@ -13210,7 +13368,7 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
13210
13368
  const api = {};
13211
13369
 
13212
13370
  Object.assign(api, {
13213
- version: '5.9.0',
13371
+ version: '5.9.2',
13214
13372
  options,
13215
13373
  request,
13216
13374
 
@@ -13326,8 +13484,10 @@ function swell(initStore = undefined, initKey, initOptions = {}) {
13326
13484
 
13327
13485
  const session = allOptions.session || allOptions.getCookie('swell-session');
13328
13486
  const locale = allOptions.locale || allOptions.getCookie('swell-locale');
13487
+ const cookieCurrency = allOptions.getCookie('swell-currency');
13329
13488
  const currency =
13330
- allOptions.currency || allOptions.getCookie('swell-currency');
13489
+ allOptions.currency ||
13490
+ (isCurrencyCode(cookieCurrency) ? cookieCurrency : undefined);
13331
13491
  const path = allOptions.path || '/api';
13332
13492
 
13333
13493
  const baseUrl = `${allOptions.url}${allOptions.base || ''}${path}`;