@getspot/spot-widget 0.2.0 → 1.0.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.
@@ -1,5 +1,5 @@
1
1
 
2
- > @getspot/spot-widget@0.2.0 build /builds/getspot/spot-widget/packages/core
2
+ > @getspot/spot-widget@1.0.0 build /builds/getspot/spot-widget/packages/core
3
3
  > vite build
4
4
 
5
5
  The CJS build of Vite's Node API is deprecated. See https://vite.dev/guide/troubleshooting.html#vite-cjs-node-api-deprecated for more details.
@@ -8,6 +8,6 @@ transforming...
8
8
  ✓ 5 modules transformed.
9
9
  rendering chunks...
10
10
  computing gzip size...
11
- dist/index.umd.js 22.08 kB │ gzip: 7.07 kB
12
- dist/index.es.js 24.17 kB │ gzip: 7.31 kB
13
- ✓ built in 149ms
11
+ dist/index.umd.js 22.95 kB │ gzip: 7.21 kB
12
+ dist/index.es.js 25.38 kB │ gzip: 7.48 kB
13
+ ✓ built in 159ms
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # @getspot/spot-widget
2
2
 
3
+ ## 1.0.0
4
+
5
+ ### Major Changes
6
+
7
+ - 4f9e10e: First major release of all the widget variants.
8
+
9
+ This is really a major release for the sake of having our first major bump. The package is now ready for external use.
10
+
11
+ Includes updated functionality for updating quotes.
12
+
3
13
  ## 0.2.0
4
14
 
5
15
  ### Minor Changes
package/dist/index.es.js CHANGED
@@ -1,23 +1,23 @@
1
1
  async function b(s, e, t) {
2
2
  try {
3
- const o = await fetch(s, {
3
+ const r = await fetch(s, {
4
4
  method: "POST",
5
5
  headers: {
6
6
  "Content-Type": "application/json",
7
7
  "X-Spot-Partner-Id": e
8
8
  },
9
9
  body: JSON.stringify(t)
10
- }), n = await o.json();
11
- if (!o.ok) {
12
- const r = new Error((n == null ? void 0 : n.message) || "Failed to fetch quote");
13
- throw r.status = o.status, r.responseBody = n, r;
10
+ }), n = await r.json();
11
+ if (!r.ok) {
12
+ const o = new Error((n == null ? void 0 : n.message) || "Failed to fetch quote");
13
+ throw o.status = r.status, o.responseBody = n, o;
14
14
  }
15
15
  return n;
16
- } catch (o) {
17
- throw o instanceof Error ? o : new Error("Unknown error occurred while fetching quote");
16
+ } catch (r) {
17
+ throw r instanceof Error ? r : new Error("Unknown error occurred while fetching quote");
18
18
  }
19
19
  }
20
- const w = {
20
+ const y = {
21
21
  sandbox: "https://api.sandbox.getspot.com/v1/quote",
22
22
  production: "https://api.getspot.com/v1/quote"
23
23
  };
@@ -25,17 +25,17 @@ function _(s) {
25
25
  const {
26
26
  apiConfig: e = {},
27
27
  quoteRequestData: t,
28
- callbacks: o = {},
28
+ callbacks: r = {},
29
29
  location: n,
30
- theme: r
30
+ theme: o
31
31
  } = s, {
32
32
  environment: a = "sandbox",
33
33
  partnerId: p,
34
- endpoint: l
34
+ endpoint: c
35
35
  } = e;
36
36
  if (!p || typeof p != "string")
37
37
  throw new Error("Invalid or missing partnerId in apiConfig");
38
- if (!(l || w[a]))
38
+ if (!(c || y[a]))
39
39
  throw new Error(`Invalid environment in apiConfig: ${a}`);
40
40
  if (!t || typeof t != "object")
41
41
  throw new Error("quoteRequestData must be a non-null object");
@@ -50,14 +50,14 @@ function _(s) {
50
50
  "productId",
51
51
  "cartId",
52
52
  "productName"
53
- ].forEach((c) => {
54
- if (!Object.prototype.hasOwnProperty.call(t, c) || t[c] === void 0 || t[c] === null)
55
- throw new Error(`Missing required quoteRequestData field: '${c}'`);
53
+ ].forEach((u) => {
54
+ if (!Object.prototype.hasOwnProperty.call(t, u) || t[u] === void 0 || t[u] === null)
55
+ throw new Error(`Missing required quoteRequestData field: '${u}'`);
56
56
  });
57
- const f = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
58
- if (!f.test(t.startDate))
57
+ const m = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
58
+ if (!m.test(t.startDate))
59
59
  throw new Error("startDate must be a valid ISO8601 string");
60
- if (!f.test(t.endDate))
60
+ if (!m.test(t.endDate))
61
61
  throw new Error("endDate must be a valid ISO8601 string");
62
62
  if (typeof t.currencyCode != "string")
63
63
  throw new Error("currencyCode must be a string");
@@ -67,10 +67,10 @@ function _(s) {
67
67
  throw new Error("eventType must be a string");
68
68
  if (typeof t.productType != "string")
69
69
  throw new Error("productType must be a string");
70
- const u = ["Pass", "Trip", "Registration"];
71
- if (!u.includes(t.productType))
70
+ const f = ["Pass", "Trip", "Registration"];
71
+ if (!f.includes(t.productType))
72
72
  throw new Error(
73
- `productType must be one of ${u.join(", ")}`
73
+ `productType must be one of ${f.join(", ")}`
74
74
  );
75
75
  if (typeof t.productDuration != "string")
76
76
  throw new Error("productDuration must be a string");
@@ -93,22 +93,22 @@ function _(s) {
93
93
  "onQuoteRetrieved",
94
94
  "onError",
95
95
  "noMatchingQuote"
96
- ].forEach((c) => {
97
- const g = o[c];
96
+ ].forEach((u) => {
97
+ const g = r[u];
98
98
  if (g && typeof g != "function")
99
- throw new Error(`Callback '${c}' must be a function.`);
99
+ throw new Error(`Callback '${u}' must be a function.`);
100
100
  }), typeof n == "string" && !document.querySelector(n))
101
101
  throw new Error(`Invalid location selector: '${n}'`);
102
- if (r && typeof r != "object")
102
+ if (o && typeof o != "object")
103
103
  throw new Error(
104
104
  "Theme must be an object with CSS variables, do not include the '--' prefix"
105
105
  );
106
106
  }
107
- function i(s, { text: e, className: t, parent: o, innerHTML: n } = {}) {
108
- const r = document.createElement(s);
109
- return t && (r.className = t), e != null && (r.textContent = e), n != null && (r.innerHTML = n), o && o.appendChild(r), r;
107
+ function i(s, { text: e, className: t, parent: r, innerHTML: n } = {}) {
108
+ const o = document.createElement(s);
109
+ return t && (o.className = t), e != null && (o.textContent = e), n != null && (o.innerHTML = n), r && r.appendChild(o), o;
110
110
  }
111
- function y(s, { name: e, description: t }) {
111
+ function C(s, { name: e, description: t }) {
112
112
  i("div", {
113
113
  className: "spot-header__title",
114
114
  text: e,
@@ -119,46 +119,46 @@ function y(s, { name: e, description: t }) {
119
119
  parent: s
120
120
  });
121
121
  }
122
- function C(s, e = []) {
122
+ function v(s, e = []) {
123
123
  const t = i("ul", {
124
124
  className: "spot-benefits__list",
125
125
  parent: s
126
126
  });
127
- e.forEach((o) => {
127
+ e.forEach((r) => {
128
128
  const n = i("li", { parent: t });
129
129
  n.innerHTML = `
130
130
  <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
131
131
  <path d="M11.6666 3.5L5.24998 9.91667L2.33331 7"
132
132
  stroke="#2E2E2E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
133
- </svg>`, i("span", { text: o, parent: n });
133
+ </svg>`, i("span", { text: r, parent: n });
134
134
  });
135
135
  }
136
- function v(s, e = []) {
136
+ function E(s, e = []) {
137
137
  const t = i("div", {
138
138
  className: "spot-table__container",
139
139
  parent: s
140
- }), o = i("table", {
140
+ }), r = i("table", {
141
141
  className: "spot-refund__table spot-table--dynamic",
142
142
  parent: t
143
- }), n = i("thead", { parent: o }), r = i("tr", { parent: n });
144
- i("th", { text: "When you cancel", parent: r }), i("th", { text: "You will receive", parent: r });
145
- const a = i("tbody", { parent: o });
146
- e.forEach(({ text: p, percent: l, amount: d }) => {
147
- const m = i("tr", { parent: a });
148
- i("td", { text: p, parent: m });
149
- const f = l === "Not eligible for refund" ? "Not eligible for a refund" : `$${d} refund`;
150
- i("td", { text: f, parent: m });
143
+ }), n = i("thead", { parent: r }), o = i("tr", { parent: n });
144
+ i("th", { text: "When you cancel", parent: o }), i("th", { text: "You will receive", parent: o });
145
+ const a = i("tbody", { parent: r });
146
+ e.forEach(({ text: p, percent: c, amount: l }) => {
147
+ const d = i("tr", { parent: a });
148
+ i("td", { text: p, parent: d });
149
+ const m = c === "Not eligible for refund" ? "Not eligible for a refund" : `$${l} refund`;
150
+ i("td", { text: m, parent: d });
151
151
  });
152
152
  }
153
- function E(s, e, t) {
154
- const o = i("div", {
153
+ function k(s, e, t) {
154
+ const r = i("div", {
155
155
  className: "spot-selection__options",
156
156
  parent: s
157
157
  }), n = i("label", {
158
158
  className: `spot-selection__option ${t ? "selected" : ""}`,
159
- parent: o
160
- }), r = i("input", { parent: n });
161
- r.type = "radio", r.name = "selection", r.value = "yes", t && (r.checked = !0), i("strong", {
159
+ parent: r
160
+ }), o = i("input", { parent: n });
161
+ o.type = "radio", o.name = "selection", o.value = "yes", t && (o.checked = !0), i("strong", {
162
162
  text: `Yes, protect my booking for $${e}`,
163
163
  parent: n
164
164
  }), i("span", {
@@ -168,26 +168,26 @@ function E(s, e, t) {
168
168
  });
169
169
  const a = i("label", {
170
170
  className: "spot-selection__option",
171
- parent: o
171
+ parent: r
172
172
  }), p = i("input", { parent: a });
173
- return p.type = "radio", p.name = "selection", p.value = "no", i("span", { text: "No, do not protect my booking", parent: a }), o;
173
+ return p.type = "radio", p.name = "selection", p.value = "no", i("span", { text: "No, do not protect my booking", parent: a }), r;
174
174
  }
175
- function k(s, e) {
175
+ function q(s, e) {
176
176
  const t = i("div", {
177
177
  className: "spot-footer__container",
178
178
  parent: s
179
- }), o = i("div", {
179
+ }), r = i("div", {
180
180
  className: "spot-footer__terms",
181
181
  parent: t
182
182
  });
183
183
  i("span", {
184
184
  innerHTML: e.communication.legalDisclaimer,
185
- parent: o
186
- }), i("br", { parent: o }), i("a", {
185
+ parent: r
186
+ }), i("br", { parent: r }), i("a", {
187
187
  href: e.communication.termsAndConditionsUrl,
188
188
  className: "spot-footer__terms-link",
189
189
  text: "Refund Guarantee Terms and Conditions",
190
- parent: o
190
+ parent: r
191
191
  });
192
192
  const n = i("p", {
193
193
  className: "spot-footer__powered-by",
@@ -216,7 +216,7 @@ function H(s) {
216
216
  e.textContent = s, document.head.appendChild(e);
217
217
  }
218
218
  H(x);
219
- const q = {
219
+ const w = {
220
220
  sandbox: "https://api.sandbox.getspot.com/api/v1/quote",
221
221
  production: "https://api.getspot.com/api/v1/quote"
222
222
  };
@@ -233,16 +233,16 @@ class I {
233
233
  }, this._onResize = this._updateLayout.bind(this), this.root = typeof this.options.location == "string" ? document.querySelector(this.options.location) : this.options.location, this.currentSelection = this.options.optInSelected ? "yes" : null, this._init();
234
234
  }
235
235
  async _init() {
236
- var e, t, o, n;
236
+ var e, t, r, n, o;
237
237
  try {
238
238
  _(this.options);
239
239
  const {
240
- environment: r,
241
- partnerId: a,
242
- endpoint: p
243
- } = this.options.apiConfig, l = p || q[r], d = await b(
240
+ environment: a,
241
+ partnerId: p,
242
+ endpoint: c
243
+ } = this.options.apiConfig, l = c || w[a], d = await b(
244
244
  l,
245
- a,
245
+ p,
246
246
  this.options.quoteRequestData
247
247
  );
248
248
  if (d.status !== "QUOTE_AVAILABLE") {
@@ -256,44 +256,44 @@ class I {
256
256
  status: "QUOTE_ACCEPTED",
257
257
  spotPrice: this.quote.spotPrice,
258
258
  quoteId: this.quote.id
259
- }), (o = this.options.callbacks) != null && o.onQuoteRetrieved && this.options.callbacks.onQuoteRetrieved(this.quote);
260
- } catch (r) {
261
- (n = this.options.callbacks) == null || n.onError({
262
- message: r.message,
263
- status: r.status,
264
- responseBody: r.responseBody
265
- });
259
+ }), (r = this.options.callbacks) != null && r.onQuoteRetrieved && this.options.callbacks.onQuoteRetrieved(this.quote);
260
+ } catch (a) {
261
+ (n = this.options.callbacks) != null && n.onError && ((o = this.options.callbacks) == null || o.onError({
262
+ message: a.message,
263
+ status: a.status,
264
+ responseBody: a.responseBody
265
+ }));
266
266
  }
267
267
  }
268
268
  _renderWidget() {
269
- this.container = document.createElement("div"), this.container.className = "spot-refund-guarantee", this.root.appendChild(this.container), Object.entries(this.options.theme || {}).forEach(([o, n]) => {
270
- const r = `--${o}`;
271
- this.container.style.setProperty(r, n);
272
- }), y(this.container, this.quote.communication);
269
+ this.container = document.createElement("div"), this.container.className = "spot-refund-guarantee", this.root.appendChild(this.container), Object.entries(this.options.theme || {}).forEach(([r, n]) => {
270
+ const o = `--${r}`;
271
+ this.container.style.setProperty(o, n);
272
+ }), C(this.container, this.quote.communication);
273
273
  const e = document.createElement("div");
274
- e.className = "spot-content__wrapper", this.container.appendChild(e), C(e, this.quote.communication.bulletPoints), this.options.showTable && v(e, this.quote.payoutSchedule);
275
- const t = E(
274
+ e.className = "spot-content__wrapper", this.container.appendChild(e), v(e, this.quote.communication.bulletPoints), this.options.showTable && E(e, this.quote.payoutSchedule);
275
+ const t = k(
276
276
  e,
277
277
  this.quote.spotPrice,
278
278
  this.options.optInSelected
279
279
  );
280
- e.appendChild(t), k(this.container, this.quote), window.addEventListener("resize", this._onResize), this._updateLayout(), this._setupOptionListeners(t);
280
+ e.appendChild(t), q(this.container, this.quote), window.addEventListener("resize", this._onResize), this._updateLayout(), this._setupOptionListeners(t);
281
281
  }
282
282
  _updateLayout() {
283
283
  const e = window.matchMedia("(min-width: 768px)").matches;
284
284
  this.container.querySelector(".spot-content__wrapper").classList.toggle("desktop-layout", e && this.options.showTable);
285
285
  }
286
286
  _setupOptionListeners(e) {
287
- const t = e.querySelectorAll('input[type="radio"]'), o = e.querySelectorAll(".spot-selection__option");
287
+ const t = e.querySelectorAll('input[type="radio"]'), r = e.querySelectorAll(".spot-selection__option");
288
288
  t.forEach((n) => {
289
- n.addEventListener("change", (r) => {
290
- var p, l, d;
291
- const a = r.target.value;
292
- this.hideSelectionError(), this.currentSelection = a, o.forEach((m) => m.classList.remove("selected")), (p = r.target.closest(".spot-selection__option")) == null || p.classList.add("selected"), a === "yes" && ((l = this.options.callbacks) != null && l.onOptIn) && this.options.callbacks.onOptIn({
289
+ n.addEventListener("change", (o) => {
290
+ var p, c, l;
291
+ const a = o.target.value;
292
+ this.hideSelectionError(), this.currentSelection = a, r.forEach((d) => d.classList.remove("selected")), (p = o.target.closest(".spot-selection__option")) == null || p.classList.add("selected"), a === "yes" && ((c = this.options.callbacks) != null && c.onOptIn) && this.options.callbacks.onOptIn({
293
293
  status: "QUOTE_ACCEPTED",
294
294
  spotPrice: this.quote.spotPrice,
295
295
  quoteId: this.quote.id
296
- }), a === "no" && ((d = this.options.callbacks) != null && d.onOptOut) && this.options.callbacks.onOptOut({
296
+ }), a === "no" && ((l = this.options.callbacks) != null && l.onOptOut) && this.options.callbacks.onOptOut({
297
297
  status: "QUOTE_DECLINED",
298
298
  quoteId: this.quote.id
299
299
  });
@@ -321,6 +321,38 @@ class I {
321
321
  );
322
322
  return e ? this.hideSelectionError() : this.showSelectionError(), e;
323
323
  }
324
+ async updateQuote(e) {
325
+ var t, r, n;
326
+ try {
327
+ const o = {
328
+ ...this.options,
329
+ quoteRequestData: {
330
+ ...this.options.quoteRequestData,
331
+ ...e
332
+ }
333
+ };
334
+ _(o);
335
+ const {
336
+ environment: a,
337
+ partnerId: p,
338
+ endpoint: c
339
+ } = this.options.apiConfig, l = c || w[a], d = await b(
340
+ l,
341
+ p,
342
+ o.quoteRequestData
343
+ );
344
+ return d.status !== "QUOTE_AVAILABLE" ? (d.status === "NO_MATCHING_QUOTE" && ((t = this.options.callbacks) != null && t.noMatchingQuote) && this.options.callbacks.noMatchingQuote({
345
+ status: "NO_MATCHING_QUOTE",
346
+ data: o.quoteRequestData
347
+ }), !1) : (this.options.quoteRequestData = o.quoteRequestData, this.quote = d.data, this.currentSelection = null, this.destroy(), this._renderWidget(), (r = this.options.callbacks) != null && r.onQuoteRetrieved && this.options.callbacks.onQuoteRetrieved(this.quote), !0);
348
+ } catch (o) {
349
+ return (n = this.options.callbacks) == null || n.onError({
350
+ message: o.message,
351
+ status: o.status,
352
+ responseBody: o.responseBody
353
+ }), !1;
354
+ }
355
+ }
324
356
  getSelection() {
325
357
  var e, t;
326
358
  return this.currentSelection == null ? null : {
package/dist/index.umd.js CHANGED
@@ -1,8 +1,8 @@
1
- (function(f,m){typeof exports=="object"&&typeof module<"u"?module.exports=m():typeof define=="function"&&define.amd?define(m):(f=typeof globalThis<"u"?globalThis:f||self,f.SpotWidget=m())})(this,function(){"use strict";async function f(s,e,t){try{const o=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json","X-Spot-Partner-Id":e},body:JSON.stringify(t)}),n=await o.json();if(!o.ok){const r=new Error((n==null?void 0:n.message)||"Failed to fetch quote");throw r.status=o.status,r.responseBody=n,r}return n}catch(o){throw o instanceof Error?o:new Error("Unknown error occurred while fetching quote")}}const m={sandbox:"https://api.sandbox.getspot.com/v1/quote",production:"https://api.getspot.com/v1/quote"};function _(s){const{apiConfig:e={},quoteRequestData:t,callbacks:o={},location:n,theme:r}=s,{environment:a="sandbox",partnerId:p,endpoint:l}=e;if(!p||typeof p!="string")throw new Error("Invalid or missing partnerId in apiConfig");if(!(l||m[a]))throw new Error(`Invalid environment in apiConfig: ${a}`);if(!t||typeof t!="object")throw new Error("quoteRequestData must be a non-null object");["startDate","endDate","currencyCode","eventType","productType","productDuration","productPrice","productId","cartId","productName"].forEach(c=>{if(!Object.prototype.hasOwnProperty.call(t,c)||t[c]===void 0||t[c]===null)throw new Error(`Missing required quoteRequestData field: '${c}'`)});const h=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;if(!h.test(t.startDate))throw new Error("startDate must be a valid ISO8601 string");if(!h.test(t.endDate))throw new Error("endDate must be a valid ISO8601 string");if(typeof t.currencyCode!="string")throw new Error("currencyCode must be a string");if(!["USD","CAD","AUD"].includes(t.currencyCode))throw new Error(`Invalid currency code: ${t.currencyCode}`);if(typeof t.eventType!="string")throw new Error("eventType must be a string");if(typeof t.productType!="string")throw new Error("productType must be a string");const g=["Pass","Trip","Registration"];if(!g.includes(t.productType))throw new Error(`productType must be one of ${g.join(", ")}`);if(typeof t.productDuration!="string")throw new Error("productDuration must be a string");const b=["Daily","Seasonal","Trip","Event"];if(!b.includes(t.productDuration))throw new Error(`productDuration must be one of ${b.join(", ")}`);if(typeof t.productPrice!="number"||isNaN(t.productPrice))throw new Error("productPrice must be a valid number");if(typeof t.productId!="string")throw new Error("productId must be a string");if(typeof t.cartId!="string")throw new Error("cartId must be a string");if(typeof t.productName!="string")throw new Error("productName must be a string");if(["onOptIn","onOptOut","onQuoteRetrieved","onError","noMatchingQuote"].forEach(c=>{const w=o[c];if(w&&typeof w!="function")throw new Error(`Callback '${c}' must be a function.`)}),typeof n=="string"&&!document.querySelector(n))throw new Error(`Invalid location selector: '${n}'`);if(r&&typeof r!="object")throw new Error("Theme must be an object with CSS variables, do not include the '--' prefix")}function i(s,{text:e,className:t,parent:o,innerHTML:n}={}){const r=document.createElement(s);return t&&(r.className=t),e!=null&&(r.textContent=e),n!=null&&(r.innerHTML=n),o&&o.appendChild(r),r}function y(s,{name:e,description:t}){i("div",{className:"spot-header__title",text:e,parent:s}),i("div",{className:"spot-header__description",text:t,parent:s})}function C(s,e=[]){const t=i("ul",{className:"spot-benefits__list",parent:s});e.forEach(o=>{const n=i("li",{parent:t});n.innerHTML=`
1
+ (function(f,m){typeof exports=="object"&&typeof module<"u"?module.exports=m():typeof define=="function"&&define.amd?define(m):(f=typeof globalThis<"u"?globalThis:f||self,f.SpotWidget=m())})(this,function(){"use strict";async function f(s,e,t){try{const r=await fetch(s,{method:"POST",headers:{"Content-Type":"application/json","X-Spot-Partner-Id":e},body:JSON.stringify(t)}),n=await r.json();if(!r.ok){const o=new Error((n==null?void 0:n.message)||"Failed to fetch quote");throw o.status=r.status,o.responseBody=n,o}return n}catch(r){throw r instanceof Error?r:new Error("Unknown error occurred while fetching quote")}}const m={sandbox:"https://api.sandbox.getspot.com/v1/quote",production:"https://api.getspot.com/v1/quote"};function g(s){const{apiConfig:e={},quoteRequestData:t,callbacks:r={},location:n,theme:o}=s,{environment:a="sandbox",partnerId:p,endpoint:c}=e;if(!p||typeof p!="string")throw new Error("Invalid or missing partnerId in apiConfig");if(!(c||m[a]))throw new Error(`Invalid environment in apiConfig: ${a}`);if(!t||typeof t!="object")throw new Error("quoteRequestData must be a non-null object");["startDate","endDate","currencyCode","eventType","productType","productDuration","productPrice","productId","cartId","productName"].forEach(u=>{if(!Object.prototype.hasOwnProperty.call(t,u)||t[u]===void 0||t[u]===null)throw new Error(`Missing required quoteRequestData field: '${u}'`)});const h=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;if(!h.test(t.startDate))throw new Error("startDate must be a valid ISO8601 string");if(!h.test(t.endDate))throw new Error("endDate must be a valid ISO8601 string");if(typeof t.currencyCode!="string")throw new Error("currencyCode must be a string");if(!["USD","CAD","AUD"].includes(t.currencyCode))throw new Error(`Invalid currency code: ${t.currencyCode}`);if(typeof t.eventType!="string")throw new Error("eventType must be a string");if(typeof t.productType!="string")throw new Error("productType must be a string");const _=["Pass","Trip","Registration"];if(!_.includes(t.productType))throw new Error(`productType must be one of ${_.join(", ")}`);if(typeof t.productDuration!="string")throw new Error("productDuration must be a string");const w=["Daily","Seasonal","Trip","Event"];if(!w.includes(t.productDuration))throw new Error(`productDuration must be one of ${w.join(", ")}`);if(typeof t.productPrice!="number"||isNaN(t.productPrice))throw new Error("productPrice must be a valid number");if(typeof t.productId!="string")throw new Error("productId must be a string");if(typeof t.cartId!="string")throw new Error("cartId must be a string");if(typeof t.productName!="string")throw new Error("productName must be a string");if(["onOptIn","onOptOut","onQuoteRetrieved","onError","noMatchingQuote"].forEach(u=>{const y=r[u];if(y&&typeof y!="function")throw new Error(`Callback '${u}' must be a function.`)}),typeof n=="string"&&!document.querySelector(n))throw new Error(`Invalid location selector: '${n}'`);if(o&&typeof o!="object")throw new Error("Theme must be an object with CSS variables, do not include the '--' prefix")}function i(s,{text:e,className:t,parent:r,innerHTML:n}={}){const o=document.createElement(s);return t&&(o.className=t),e!=null&&(o.textContent=e),n!=null&&(o.innerHTML=n),r&&r.appendChild(o),o}function C(s,{name:e,description:t}){i("div",{className:"spot-header__title",text:e,parent:s}),i("div",{className:"spot-header__description",text:t,parent:s})}function v(s,e=[]){const t=i("ul",{className:"spot-benefits__list",parent:s});e.forEach(r=>{const n=i("li",{parent:t});n.innerHTML=`
2
2
  <svg width="14" height="14" viewBox="0 0 14 14" fill="none">
3
3
  <path d="M11.6666 3.5L5.24998 9.91667L2.33331 7"
4
4
  stroke="#2E2E2E" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
5
- </svg>`,i("span",{text:o,parent:n})})}function v(s,e=[]){const t=i("div",{className:"spot-table__container",parent:s}),o=i("table",{className:"spot-refund__table spot-table--dynamic",parent:t}),n=i("thead",{parent:o}),r=i("tr",{parent:n});i("th",{text:"When you cancel",parent:r}),i("th",{text:"You will receive",parent:r});const a=i("tbody",{parent:o});e.forEach(({text:p,percent:l,amount:d})=>{const u=i("tr",{parent:a});i("td",{text:p,parent:u});const h=l==="Not eligible for refund"?"Not eligible for a refund":`$${d} refund`;i("td",{text:h,parent:u})})}function E(s,e,t){const o=i("div",{className:"spot-selection__options",parent:s}),n=i("label",{className:`spot-selection__option ${t?"selected":""}`,parent:o}),r=i("input",{parent:n});r.type="radio",r.name="selection",r.value="yes",t&&(r.checked=!0),i("strong",{text:`Yes, protect my booking for $${e}`,parent:n}),i("span",{className:"spot-selection__recommended-tag",text:"Recommended",parent:n});const a=i("label",{className:"spot-selection__option",parent:o}),p=i("input",{parent:a});return p.type="radio",p.name="selection",p.value="no",i("span",{text:"No, do not protect my booking",parent:a}),o}function k(s,e){const t=i("div",{className:"spot-footer__container",parent:s}),o=i("div",{className:"spot-footer__terms",parent:t});i("span",{innerHTML:e.communication.legalDisclaimer,parent:o}),i("br",{parent:o}),i("a",{href:e.communication.termsAndConditionsUrl,className:"spot-footer__terms-link",text:"Refund Guarantee Terms and Conditions",parent:o});const n=i("p",{className:"spot-footer__powered-by",parent:t});return n.innerHTML=`
5
+ </svg>`,i("span",{text:r,parent:n})})}function E(s,e=[]){const t=i("div",{className:"spot-table__container",parent:s}),r=i("table",{className:"spot-refund__table spot-table--dynamic",parent:t}),n=i("thead",{parent:r}),o=i("tr",{parent:n});i("th",{text:"When you cancel",parent:o}),i("th",{text:"You will receive",parent:o});const a=i("tbody",{parent:r});e.forEach(({text:p,percent:c,amount:l})=>{const d=i("tr",{parent:a});i("td",{text:p,parent:d});const h=c==="Not eligible for refund"?"Not eligible for a refund":`$${l} refund`;i("td",{text:h,parent:d})})}function k(s,e,t){const r=i("div",{className:"spot-selection__options",parent:s}),n=i("label",{className:`spot-selection__option ${t?"selected":""}`,parent:r}),o=i("input",{parent:n});o.type="radio",o.name="selection",o.value="yes",t&&(o.checked=!0),i("strong",{text:`Yes, protect my booking for $${e}`,parent:n}),i("span",{className:"spot-selection__recommended-tag",text:"Recommended",parent:n});const a=i("label",{className:"spot-selection__option",parent:r}),p=i("input",{parent:a});return p.type="radio",p.name="selection",p.value="no",i("span",{text:"No, do not protect my booking",parent:a}),r}function x(s,e){const t=i("div",{className:"spot-footer__container",parent:s}),r=i("div",{className:"spot-footer__terms",parent:t});i("span",{innerHTML:e.communication.legalDisclaimer,parent:r}),i("br",{parent:r}),i("a",{href:e.communication.termsAndConditionsUrl,className:"spot-footer__terms-link",text:"Refund Guarantee Terms and Conditions",parent:r});const n=i("p",{className:"spot-footer__powered-by",parent:t});return n.innerHTML=`
6
6
  <svg width="145" height="28" viewBox="0 0 145 28" fill="none" xmlns="http://www.w3.org/2000/svg">
7
7
  <rect width="145" height="28"/>
8
8
  <rect x="-655" y="-270" width="819" height="325" rx="10"/>
@@ -17,4 +17,4 @@
17
17
  <rect width="45.405" height="14.8867" fill="white" transform="translate(87 8)"/>
18
18
  </clipPath>
19
19
  </defs>
20
- </svg>`,t}const x=":root{--spot-font-family: Arial;--spot-padding: 1.25rem;--spot-background-color: #ffffff;--spot-font-color: #000000;--spot-border-radius: .5rem;--spot-title-font-size: 1.25rem;--spot-title-font-weight: 700;--spot-title-padding: 0 0 1.25rem 0;--spot-description-font-size: .875rem;--spot-description-font-weight: 400;--spot-description-padding: 0 0 .5rem 0;--spot-bullets-font-size: .875rem;--spot-bullets-font-weight: 400;--spot-bullets-padding: .3125rem;--spot-table-border-radius: .625rem;--spot-table-header-font-size: .875rem;--spot-table-header-font-weight: 700;--spot-table-header-padding: 0 .5rem .625rem;--spot-table-cell-font-size: .815rem;--spot-table-cell-font-weight: 400;--spot-table-cell-padding: 0 .625rem;--spot-radio-border: #000000;--spot-radio-border-radius: .625rem;--spot-radio-checked-background: #000000;--spot-radio-text-font-size: .875rem;--spot-radio-text-font-weight: 400;--spot-radio-text-padding: .625rem;--spot-radio-selection-background: #f4f4f4;--spot-radio-selection-border-radius: .625rem;--spot-radio-selection-padding: .625rem;--spot-recommended-tag-background: #000000;--spot-recommended-tag-font-color: #ffffff;--spot-recommended-tag-font-size: .875rem;--spot-recommended-tag-font-weight: 700;--spot-recommended-tag-padding: .25rem .5rem;--spot-recommended-tag-border-radius: .5rem;--spot-selection-error-font-color: #ff0000;--spot-selection-error-font-size: .875rem;--spot-selection-error-padding: .5rem;--spot-terms-font-size: .75rem;--spot-terms-font-weight: 400;--spot-terms-font-color: #636569;--spot-terms-padding: 0;--spot-terms-link-text-decoration: underline;--spot-terms-link-font-size: .75rem;--spot-terms-link-font-weight: 400;--spot-terms-link-font-color: #636569;--spot-terms-link-padding: 0}.spot-refund-guarantee{font-family:var(--spot-font-family);padding:var(--spot-padding);background-color:var(--spot-background-color);color:var(--spot-font-color);border:.0625rem solid #e0e0e0;border-radius:var(--spot-border-radius);max-width:51rem;margin:1rem}.spot-refund-guarantee *{color:inherit}.spot-header__title{font-size:var(--spot-title-font-size);font-weight:var(--spot-title-font-weight);padding:var(--spot-title-padding);color:var(--spot-title-font-color);font-family:var(--spot-title-font-family);line-height:120%;letter-spacing:-.03125rem}.spot-header__description{font-size:var(--spot-description-font-size);font-weight:var(--spot-description-font-weight);color:var(--spot-description-font-color);font-family:var(--spot-description-font-family);padding:var(--spot-description-padding);line-height:125%;letter-spacing:-.025rem}.spot-content__wrapper{display:flex;flex-direction:column}@media (min-width: 48rem){.spot-content__wrapper.desktop-layout{display:grid;grid-template-columns:1fr 20.3125rem;align-items:start;gap:1rem}.desktop-layout .spot-benefits__list{grid-row:1}.desktop-layout .spot-selection__options{grid-row:2}.desktop-layout .spot-table__container{grid-row:1 / span 2}}@media (max-width: 52.438rem){.spot-selection__recommended-tag{display:inline-block;margin-left:0}}@media (max-width: 47.938rem){.spot-selection__recommended-tag{margin-top:0rem}}@media (max-width: 32.125rem){.spot-selection__recommended-tag{margin-top:.5rem}}@media (max-width: 47.9375rem){.spot-table__container{display:flex;justify-content:center}.spot-selection__recommended-tag{display:inline-block;margin-left:0}.spot-footer__container{flex-direction:column;margin-top:.5rem}.spot-refund__table{width:100%;table-layout:auto}.spot-refund__table th{padding:0rem}}.spot-benefits__list{list-style-type:none;line-height:125%;gap:.5625rem;font-size:var(--spot-bullets-font-size);font-weight:var(--spot-bullets-font-weight);color:var(--spot-bullets-font-color);font-family:var(--spot-bullets-font-family);padding:var(--spot-bullets-padding);margin-block-start:0rem;margin-block-end:0rem}.spot-benefits__list li{margin-bottom:.5rem;display:flex;align-items:flex-start;gap:.5rem}.spot-benefits__list li svg{flex-shrink:0;position:relative;top:.125rem}.spot-table__container{width:100%}.spot-refund__table{max-width:22rem;border-radius:var(--spot-table-border-radius);overflow:hidden;border:.09375rem solid #636569;table-layout:fixed;margin-bottom:1.5rem;margin-top:.25rem;padding:.625rem}.spot-refund__table--dynamic{height:auto!important;min-height:7.5rem}.spot-refund__table td,.spot-refund__table th{padding:.375rem .625rem;text-align:left}.spot-refund__table th{text-align:left;font-size:var(--spot-table-header-font-size);font-weight:var(--spot-table-header-font-weight);color:var(--spot-table-header-font-color);font-family:var(--spot-table-header-font-family);padding:var(--spot-table-header-padding)}.spot-refund__table td{text-align:left;font-size:var(--spot-table-cell-font-size);font-weight:var(--spot-table-cell-font-weight);color:var(--spot-table-cell-font-color);font-family:var(--spot-table-cell-font-family);padding:var(--spot-table-cell-padding)}input[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:.75rem;height:.75rem;border:.0625rem solid var(--spot-radio-border);border-radius:var(--spot-radio-border-radius);margin-right:.5rem;position:relative;vertical-align:middle;top:-.0625rem;cursor:pointer}input[type=radio]:checked{background:var(--spot-radio-checked-background);box-shadow:inset 0 0 0 .0625rem #fff}.spot-selection__options{display:flex;flex-direction:column;gap:.5rem}.spot-selection__option{display:block;position:relative;transition:background .2s;cursor:pointer;font-size:var(--spot-radio-text-font-size);font-weight:var(--spot-radio-text-font-weight);color:var(--spot-radio-text-font-color);font-family:var(--spot-radio-text-font-family);padding:var(--spot-radio-text-padding);margin-right:.5rem;gap:.5rem;flex:1 0 0;align-self:stretch}.spot-selection__option.selected{background:var(--spot-radio-selection-background);border-radius:var(--spot-radio-selection-border-radius);padding:var(--spot-radio-selection-padding)}.spot-selection__recommended-tag{background:var(--spot-recommended-tag-background);color:var(--spot-recommended-tag-font-color);font-size:var(--spot-recommended-tag-font-size);font-weight:var(--spot-recommended-tag-font-weight);padding:var(--spot-recommended-tag-padding);border-radius:var(--spot-recommended-tag-border-radius);margin-left:1.5rem;white-space:nowrap}.spot-selection__error{color:var(--spot-selection-error-font-color);font-size:var(--spot-selection-error-font-size);padding:var(--spot-selection-error-padding);display:none}.spot-footer__terms{margin-top:.625rem;margin-right:.25rem;font-size:var(--spot-terms-font-size);font-weight:var(--spot-terms-font-weight);color:var(--spot-terms-font-color);font-family:var(--spot-terms-font-family);padding:var(--spot-terms-padding)}.spot-footer__terms-link{text-decoration:var(--spot-terms-link-text-decoration);font-size:var(--spot-terms-link-font-size);font-weight:var(--spot-terms-link-font-weight);color:var(--spot-terms-link-font-color);font-family:var(--spot-terms-link-font-family);padding:var(--spot-terms-link-padding)}.spot-footer__container{display:flex;justify-content:space-between;align-items:center}.spot-footer__powered-by{margin-top:1.5rem}";function H(s){const e=document.createElement("style");e.textContent=s,document.head.appendChild(e)}H(x);const q={sandbox:"https://api.sandbox.getspot.com/api/v1/quote",production:"https://api.getspot.com/api/v1/quote"};class T{constructor(e={}){this.options={location:"body",showTable:!0,optInSelected:!1,apiConfig:{environment:"production",partnerId:""},quoteRequestData:{},callbacks:{},...e},this._onResize=this._updateLayout.bind(this),this.root=typeof this.options.location=="string"?document.querySelector(this.options.location):this.options.location,this.currentSelection=this.options.optInSelected?"yes":null,this._init()}async _init(){var e,t,o,n;try{_(this.options);const{environment:r,partnerId:a,endpoint:p}=this.options.apiConfig,l=p||q[r],d=await f(l,a,this.options.quoteRequestData);if(d.status!=="QUOTE_AVAILABLE"){d.status==="NO_MATCHING_QUOTE"&&((e=this.options.callbacks)!=null&&e.noMatchingQuote)&&this.options.callbacks.noMatchingQuote({status:"NO_MATCHING_QUOTE",data:this.options.quoteRequestData});return}this.quote=d.data,this._renderWidget(),this.options.optInSelected&&((t=this.options.callbacks)!=null&&t.onOptIn)&&this.options.callbacks.onOptIn({status:"QUOTE_ACCEPTED",spotPrice:this.quote.spotPrice,quoteId:this.quote.id}),(o=this.options.callbacks)!=null&&o.onQuoteRetrieved&&this.options.callbacks.onQuoteRetrieved(this.quote)}catch(r){(n=this.options.callbacks)==null||n.onError({message:r.message,status:r.status,responseBody:r.responseBody})}}_renderWidget(){this.container=document.createElement("div"),this.container.className="spot-refund-guarantee",this.root.appendChild(this.container),Object.entries(this.options.theme||{}).forEach(([o,n])=>{const r=`--${o}`;this.container.style.setProperty(r,n)}),y(this.container,this.quote.communication);const e=document.createElement("div");e.className="spot-content__wrapper",this.container.appendChild(e),C(e,this.quote.communication.bulletPoints),this.options.showTable&&v(e,this.quote.payoutSchedule);const t=E(e,this.quote.spotPrice,this.options.optInSelected);e.appendChild(t),k(this.container,this.quote),window.addEventListener("resize",this._onResize),this._updateLayout(),this._setupOptionListeners(t)}_updateLayout(){const e=window.matchMedia("(min-width: 768px)").matches;this.container.querySelector(".spot-content__wrapper").classList.toggle("desktop-layout",e&&this.options.showTable)}_setupOptionListeners(e){const t=e.querySelectorAll('input[type="radio"]'),o=e.querySelectorAll(".spot-selection__option");t.forEach(n=>{n.addEventListener("change",r=>{var p,l,d;const a=r.target.value;this.hideSelectionError(),this.currentSelection=a,o.forEach(u=>u.classList.remove("selected")),(p=r.target.closest(".spot-selection__option"))==null||p.classList.add("selected"),a==="yes"&&((l=this.options.callbacks)!=null&&l.onOptIn)&&this.options.callbacks.onOptIn({status:"QUOTE_ACCEPTED",spotPrice:this.quote.spotPrice,quoteId:this.quote.id}),a==="no"&&((d=this.options.callbacks)!=null&&d.onOptOut)&&this.options.callbacks.onOptOut({status:"QUOTE_DECLINED",quoteId:this.quote.id})})})}showSelectionError(){var e;if(!this.errorEl){this.errorEl=document.createElement("div"),this.errorEl.className="spot-selection__error",this.errorEl.textContent="Please make a selection";const t=(e=this.container)==null?void 0:e.querySelector(".spot-selection__options");t&&t.insertAdjacentElement("afterend",this.errorEl)}this.errorEl.style.display="block"}hideSelectionError(){this.errorEl&&(this.errorEl.style.display="none")}validateSelection(){if(!this.container)return!1;const e=!!this.container.querySelector('input[name="selection"]:checked');return e?this.hideSelectionError():this.showSelectionError(),e}getSelection(){var e,t;return this.currentSelection==null?null:{selection:this.currentSelection,quoteId:(e=this.quote)==null?void 0:e.id,spotPrice:(t=this.quote)==null?void 0:t.spotPrice,status:this.currentSelection==="yes"?"QUOTE_ACCEPTED":"QUOTE_DECLINED"}}destroy(){window.removeEventListener("resize",this._onResize),this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container)}}return T});
20
+ </svg>`,t}const q=":root{--spot-font-family: Arial;--spot-padding: 1.25rem;--spot-background-color: #ffffff;--spot-font-color: #000000;--spot-border-radius: .5rem;--spot-title-font-size: 1.25rem;--spot-title-font-weight: 700;--spot-title-padding: 0 0 1.25rem 0;--spot-description-font-size: .875rem;--spot-description-font-weight: 400;--spot-description-padding: 0 0 .5rem 0;--spot-bullets-font-size: .875rem;--spot-bullets-font-weight: 400;--spot-bullets-padding: .3125rem;--spot-table-border-radius: .625rem;--spot-table-header-font-size: .875rem;--spot-table-header-font-weight: 700;--spot-table-header-padding: 0 .5rem .625rem;--spot-table-cell-font-size: .815rem;--spot-table-cell-font-weight: 400;--spot-table-cell-padding: 0 .625rem;--spot-radio-border: #000000;--spot-radio-border-radius: .625rem;--spot-radio-checked-background: #000000;--spot-radio-text-font-size: .875rem;--spot-radio-text-font-weight: 400;--spot-radio-text-padding: .625rem;--spot-radio-selection-background: #f4f4f4;--spot-radio-selection-border-radius: .625rem;--spot-radio-selection-padding: .625rem;--spot-recommended-tag-background: #000000;--spot-recommended-tag-font-color: #ffffff;--spot-recommended-tag-font-size: .875rem;--spot-recommended-tag-font-weight: 700;--spot-recommended-tag-padding: .25rem .5rem;--spot-recommended-tag-border-radius: .5rem;--spot-selection-error-font-color: #ff0000;--spot-selection-error-font-size: .875rem;--spot-selection-error-padding: .5rem;--spot-terms-font-size: .75rem;--spot-terms-font-weight: 400;--spot-terms-font-color: #636569;--spot-terms-padding: 0;--spot-terms-link-text-decoration: underline;--spot-terms-link-font-size: .75rem;--spot-terms-link-font-weight: 400;--spot-terms-link-font-color: #636569;--spot-terms-link-padding: 0}.spot-refund-guarantee{font-family:var(--spot-font-family);padding:var(--spot-padding);background-color:var(--spot-background-color);color:var(--spot-font-color);border:.0625rem solid #e0e0e0;border-radius:var(--spot-border-radius);max-width:51rem;margin:1rem}.spot-refund-guarantee *{color:inherit}.spot-header__title{font-size:var(--spot-title-font-size);font-weight:var(--spot-title-font-weight);padding:var(--spot-title-padding);color:var(--spot-title-font-color);font-family:var(--spot-title-font-family);line-height:120%;letter-spacing:-.03125rem}.spot-header__description{font-size:var(--spot-description-font-size);font-weight:var(--spot-description-font-weight);color:var(--spot-description-font-color);font-family:var(--spot-description-font-family);padding:var(--spot-description-padding);line-height:125%;letter-spacing:-.025rem}.spot-content__wrapper{display:flex;flex-direction:column}@media (min-width: 48rem){.spot-content__wrapper.desktop-layout{display:grid;grid-template-columns:1fr 20.3125rem;align-items:start;gap:1rem}.desktop-layout .spot-benefits__list{grid-row:1}.desktop-layout .spot-selection__options{grid-row:2}.desktop-layout .spot-table__container{grid-row:1 / span 2}}@media (max-width: 52.438rem){.spot-selection__recommended-tag{display:inline-block;margin-left:0}}@media (max-width: 47.938rem){.spot-selection__recommended-tag{margin-top:0rem}}@media (max-width: 32.125rem){.spot-selection__recommended-tag{margin-top:.5rem}}@media (max-width: 47.9375rem){.spot-table__container{display:flex;justify-content:center}.spot-selection__recommended-tag{display:inline-block;margin-left:0}.spot-footer__container{flex-direction:column;margin-top:.5rem}.spot-refund__table{width:100%;table-layout:auto}.spot-refund__table th{padding:0rem}}.spot-benefits__list{list-style-type:none;line-height:125%;gap:.5625rem;font-size:var(--spot-bullets-font-size);font-weight:var(--spot-bullets-font-weight);color:var(--spot-bullets-font-color);font-family:var(--spot-bullets-font-family);padding:var(--spot-bullets-padding);margin-block-start:0rem;margin-block-end:0rem}.spot-benefits__list li{margin-bottom:.5rem;display:flex;align-items:flex-start;gap:.5rem}.spot-benefits__list li svg{flex-shrink:0;position:relative;top:.125rem}.spot-table__container{width:100%}.spot-refund__table{max-width:22rem;border-radius:var(--spot-table-border-radius);overflow:hidden;border:.09375rem solid #636569;table-layout:fixed;margin-bottom:1.5rem;margin-top:.25rem;padding:.625rem}.spot-refund__table--dynamic{height:auto!important;min-height:7.5rem}.spot-refund__table td,.spot-refund__table th{padding:.375rem .625rem;text-align:left}.spot-refund__table th{text-align:left;font-size:var(--spot-table-header-font-size);font-weight:var(--spot-table-header-font-weight);color:var(--spot-table-header-font-color);font-family:var(--spot-table-header-font-family);padding:var(--spot-table-header-padding)}.spot-refund__table td{text-align:left;font-size:var(--spot-table-cell-font-size);font-weight:var(--spot-table-cell-font-weight);color:var(--spot-table-cell-font-color);font-family:var(--spot-table-cell-font-family);padding:var(--spot-table-cell-padding)}input[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;width:.75rem;height:.75rem;border:.0625rem solid var(--spot-radio-border);border-radius:var(--spot-radio-border-radius);margin-right:.5rem;position:relative;vertical-align:middle;top:-.0625rem;cursor:pointer}input[type=radio]:checked{background:var(--spot-radio-checked-background);box-shadow:inset 0 0 0 .0625rem #fff}.spot-selection__options{display:flex;flex-direction:column;gap:.5rem}.spot-selection__option{display:block;position:relative;transition:background .2s;cursor:pointer;font-size:var(--spot-radio-text-font-size);font-weight:var(--spot-radio-text-font-weight);color:var(--spot-radio-text-font-color);font-family:var(--spot-radio-text-font-family);padding:var(--spot-radio-text-padding);margin-right:.5rem;gap:.5rem;flex:1 0 0;align-self:stretch}.spot-selection__option.selected{background:var(--spot-radio-selection-background);border-radius:var(--spot-radio-selection-border-radius);padding:var(--spot-radio-selection-padding)}.spot-selection__recommended-tag{background:var(--spot-recommended-tag-background);color:var(--spot-recommended-tag-font-color);font-size:var(--spot-recommended-tag-font-size);font-weight:var(--spot-recommended-tag-font-weight);padding:var(--spot-recommended-tag-padding);border-radius:var(--spot-recommended-tag-border-radius);margin-left:1.5rem;white-space:nowrap}.spot-selection__error{color:var(--spot-selection-error-font-color);font-size:var(--spot-selection-error-font-size);padding:var(--spot-selection-error-padding);display:none}.spot-footer__terms{margin-top:.625rem;margin-right:.25rem;font-size:var(--spot-terms-font-size);font-weight:var(--spot-terms-font-weight);color:var(--spot-terms-font-color);font-family:var(--spot-terms-font-family);padding:var(--spot-terms-padding)}.spot-footer__terms-link{text-decoration:var(--spot-terms-link-text-decoration);font-size:var(--spot-terms-link-font-size);font-weight:var(--spot-terms-link-font-weight);color:var(--spot-terms-link-font-color);font-family:var(--spot-terms-link-font-family);padding:var(--spot-terms-link-padding)}.spot-footer__container{display:flex;justify-content:space-between;align-items:center}.spot-footer__powered-by{margin-top:1.5rem}";function H(s){const e=document.createElement("style");e.textContent=s,document.head.appendChild(e)}H(q);const b={sandbox:"https://api.sandbox.getspot.com/api/v1/quote",production:"https://api.getspot.com/api/v1/quote"};class T{constructor(e={}){this.options={location:"body",showTable:!0,optInSelected:!1,apiConfig:{environment:"production",partnerId:""},quoteRequestData:{},callbacks:{},...e},this._onResize=this._updateLayout.bind(this),this.root=typeof this.options.location=="string"?document.querySelector(this.options.location):this.options.location,this.currentSelection=this.options.optInSelected?"yes":null,this._init()}async _init(){var e,t,r,n,o;try{g(this.options);const{environment:a,partnerId:p,endpoint:c}=this.options.apiConfig,l=c||b[a],d=await f(l,p,this.options.quoteRequestData);if(d.status!=="QUOTE_AVAILABLE"){d.status==="NO_MATCHING_QUOTE"&&((e=this.options.callbacks)!=null&&e.noMatchingQuote)&&this.options.callbacks.noMatchingQuote({status:"NO_MATCHING_QUOTE",data:this.options.quoteRequestData});return}this.quote=d.data,this._renderWidget(),this.options.optInSelected&&((t=this.options.callbacks)!=null&&t.onOptIn)&&this.options.callbacks.onOptIn({status:"QUOTE_ACCEPTED",spotPrice:this.quote.spotPrice,quoteId:this.quote.id}),(r=this.options.callbacks)!=null&&r.onQuoteRetrieved&&this.options.callbacks.onQuoteRetrieved(this.quote)}catch(a){(n=this.options.callbacks)!=null&&n.onError&&((o=this.options.callbacks)==null||o.onError({message:a.message,status:a.status,responseBody:a.responseBody}))}}_renderWidget(){this.container=document.createElement("div"),this.container.className="spot-refund-guarantee",this.root.appendChild(this.container),Object.entries(this.options.theme||{}).forEach(([r,n])=>{const o=`--${r}`;this.container.style.setProperty(o,n)}),C(this.container,this.quote.communication);const e=document.createElement("div");e.className="spot-content__wrapper",this.container.appendChild(e),v(e,this.quote.communication.bulletPoints),this.options.showTable&&E(e,this.quote.payoutSchedule);const t=k(e,this.quote.spotPrice,this.options.optInSelected);e.appendChild(t),x(this.container,this.quote),window.addEventListener("resize",this._onResize),this._updateLayout(),this._setupOptionListeners(t)}_updateLayout(){const e=window.matchMedia("(min-width: 768px)").matches;this.container.querySelector(".spot-content__wrapper").classList.toggle("desktop-layout",e&&this.options.showTable)}_setupOptionListeners(e){const t=e.querySelectorAll('input[type="radio"]'),r=e.querySelectorAll(".spot-selection__option");t.forEach(n=>{n.addEventListener("change",o=>{var p,c,l;const a=o.target.value;this.hideSelectionError(),this.currentSelection=a,r.forEach(d=>d.classList.remove("selected")),(p=o.target.closest(".spot-selection__option"))==null||p.classList.add("selected"),a==="yes"&&((c=this.options.callbacks)!=null&&c.onOptIn)&&this.options.callbacks.onOptIn({status:"QUOTE_ACCEPTED",spotPrice:this.quote.spotPrice,quoteId:this.quote.id}),a==="no"&&((l=this.options.callbacks)!=null&&l.onOptOut)&&this.options.callbacks.onOptOut({status:"QUOTE_DECLINED",quoteId:this.quote.id})})})}showSelectionError(){var e;if(!this.errorEl){this.errorEl=document.createElement("div"),this.errorEl.className="spot-selection__error",this.errorEl.textContent="Please make a selection";const t=(e=this.container)==null?void 0:e.querySelector(".spot-selection__options");t&&t.insertAdjacentElement("afterend",this.errorEl)}this.errorEl.style.display="block"}hideSelectionError(){this.errorEl&&(this.errorEl.style.display="none")}validateSelection(){if(!this.container)return!1;const e=!!this.container.querySelector('input[name="selection"]:checked');return e?this.hideSelectionError():this.showSelectionError(),e}async updateQuote(e){var t,r,n;try{const o={...this.options,quoteRequestData:{...this.options.quoteRequestData,...e}};g(o);const{environment:a,partnerId:p,endpoint:c}=this.options.apiConfig,l=c||b[a],d=await f(l,p,o.quoteRequestData);return d.status!=="QUOTE_AVAILABLE"?(d.status==="NO_MATCHING_QUOTE"&&((t=this.options.callbacks)!=null&&t.noMatchingQuote)&&this.options.callbacks.noMatchingQuote({status:"NO_MATCHING_QUOTE",data:o.quoteRequestData}),!1):(this.options.quoteRequestData=o.quoteRequestData,this.quote=d.data,this.currentSelection=null,this.destroy(),this._renderWidget(),(r=this.options.callbacks)!=null&&r.onQuoteRetrieved&&this.options.callbacks.onQuoteRetrieved(this.quote),!0)}catch(o){return(n=this.options.callbacks)==null||n.onError({message:o.message,status:o.status,responseBody:o.responseBody}),!1}}getSelection(){var e,t;return this.currentSelection==null?null:{selection:this.currentSelection,quoteId:(e=this.quote)==null?void 0:e.id,spotPrice:(t=this.quote)==null?void 0:t.spotPrice,status:this.currentSelection==="yes"?"QUOTE_ACCEPTED":"QUOTE_DECLINED"}}destroy(){window.removeEventListener("resize",this._onResize),this.container&&this.container.parentNode&&this.container.parentNode.removeChild(this.container)}}return T});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@getspot/spot-widget",
3
- "version": "0.2.0",
3
+ "version": "1.0.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
package/src/index.js CHANGED
@@ -90,11 +90,13 @@ class SpotWidget {
90
90
  this.options.callbacks.onQuoteRetrieved(this.quote);
91
91
  }
92
92
  } catch (err) {
93
- this.options.callbacks?.onError({
94
- message: err.message,
95
- status: err.status,
96
- responseBody: err.responseBody,
97
- });
93
+ if (this.options.callbacks?.onError) {
94
+ this.options.callbacks?.onError({
95
+ message: err.message,
96
+ status: err.status,
97
+ responseBody: err.responseBody,
98
+ });
99
+ }
98
100
  }
99
101
  }
100
102
 
@@ -205,6 +207,68 @@ class SpotWidget {
205
207
  return isSelected;
206
208
  }
207
209
 
210
+ async updateQuote(newQuoteRequestData) {
211
+ try {
212
+ const updatedOptions = {
213
+ ...this.options,
214
+ quoteRequestData: {
215
+ ...this.options.quoteRequestData,
216
+ ...newQuoteRequestData,
217
+ },
218
+ };
219
+
220
+ validateOptions(updatedOptions);
221
+
222
+ const {
223
+ environment,
224
+ partnerId,
225
+ endpoint: customEndpoint,
226
+ } = this.options.apiConfig;
227
+
228
+ const endpoint = customEndpoint || apiEndpoint[environment];
229
+
230
+ const response = await fetchQuote(
231
+ endpoint,
232
+ partnerId,
233
+ updatedOptions.quoteRequestData
234
+ );
235
+
236
+ if (response.status !== "QUOTE_AVAILABLE") {
237
+ if (
238
+ response.status === "NO_MATCHING_QUOTE" &&
239
+ this.options.callbacks?.noMatchingQuote
240
+ ) {
241
+ this.options.callbacks.noMatchingQuote({
242
+ status: "NO_MATCHING_QUOTE",
243
+ data: updatedOptions.quoteRequestData,
244
+ });
245
+ }
246
+ return false;
247
+ }
248
+
249
+ this.options.quoteRequestData = updatedOptions.quoteRequestData;
250
+ this.quote = response.data;
251
+ this.currentSelection = null;
252
+
253
+ this.destroy();
254
+
255
+ this._renderWidget();
256
+
257
+ if (this.options.callbacks?.onQuoteRetrieved) {
258
+ this.options.callbacks.onQuoteRetrieved(this.quote);
259
+ }
260
+
261
+ return true;
262
+ } catch (err) {
263
+ this.options.callbacks?.onError({
264
+ message: err.message,
265
+ status: err.status,
266
+ responseBody: err.responseBody,
267
+ });
268
+ return false;
269
+ }
270
+ }
271
+
208
272
  getSelection() {
209
273
  if (this.currentSelection == null) return null;
210
274