@financial-times/custom-code-component 2.0.1-alpha.6 → 2.0.1-alpha.8

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,7 +1,7 @@
1
- function m(o) {
2
- this.listenerMap = [{}, {}], o && this.root(o), this.handle = m.prototype.handle.bind(this), this._removedListeners = [];
1
+ function p(o) {
2
+ this.listenerMap = [{}, {}], o && this.root(o), this.handle = p.prototype.handle.bind(this), this._removedListeners = [];
3
3
  }
4
- m.prototype.root = function(o) {
4
+ p.prototype.root = function(o) {
5
5
  const t = this.listenerMap;
6
6
  let e;
7
7
  if (this.rootElement) {
@@ -19,24 +19,24 @@ m.prototype.root = function(o) {
19
19
  t[0].hasOwnProperty(e) && this.rootElement.addEventListener(e, this.handle, !1);
20
20
  return this;
21
21
  };
22
- m.prototype.captureForType = function(o) {
22
+ p.prototype.captureForType = function(o) {
23
23
  return ["blur", "error", "focus", "load", "resize", "scroll"].indexOf(o) !== -1;
24
24
  };
25
- m.prototype.on = function(o, t, e, n) {
26
- let r, s, i, c;
25
+ p.prototype.on = function(o, t, e, n) {
26
+ let s, r, i, c;
27
27
  if (!o)
28
28
  throw new TypeError("Invalid event type: " + o);
29
29
  if (typeof t == "function" && (n = e, e = t, t = null), n === void 0 && (n = this.captureForType(o)), typeof e != "function")
30
30
  throw new TypeError("Handler must be a type of Function");
31
- return r = this.rootElement, s = this.listenerMap[n ? 1 : 0], s[o] || (r && r.addEventListener(o, this.handle, n), s[o] = []), t ? /^[a-z]+$/i.test(t) ? (c = t, i = T) : /^#[a-z0-9\-_]+$/i.test(t) ? (c = t.slice(1), i = $) : (c = t, i = Element.prototype.matches) : (c = null, i = S.bind(this)), s[o].push({
31
+ return s = this.rootElement, r = this.listenerMap[n ? 1 : 0], r[o] || (s && s.addEventListener(o, this.handle, n), r[o] = []), t ? /^[a-z]+$/i.test(t) ? (c = t, i = T) : /^#[a-z0-9\-_]+$/i.test(t) ? (c = t.slice(1), i = S) : (c = t, i = Element.prototype.matches) : (c = null, i = $.bind(this)), r[o].push({
32
32
  selector: t,
33
33
  handler: e,
34
34
  matcher: i,
35
35
  matcherParam: c
36
36
  }), this;
37
37
  };
38
- m.prototype.off = function(o, t, e, n) {
39
- let r, s, i, c, h;
38
+ p.prototype.off = function(o, t, e, n) {
39
+ let s, r, i, c, h;
40
40
  if (typeof t == "function" && (n = e, e = t, t = null), n === void 0)
41
41
  return this.off(o, t, e, !0), this.off(o, t, e, !1), this;
42
42
  if (i = this.listenerMap[n ? 1 : 0], !o) {
@@ -46,18 +46,18 @@ m.prototype.off = function(o, t, e, n) {
46
46
  }
47
47
  if (c = i[o], !c || !c.length)
48
48
  return this;
49
- for (r = c.length - 1; r >= 0; r--)
50
- s = c[r], (!t || t === s.selector) && (!e || e === s.handler) && (this._removedListeners.push(s), c.splice(r, 1));
49
+ for (s = c.length - 1; s >= 0; s--)
50
+ r = c[s], (!t || t === r.selector) && (!e || e === r.handler) && (this._removedListeners.push(r), c.splice(s, 1));
51
51
  return c.length || (delete i[o], this.rootElement && this.rootElement.removeEventListener(o, this.handle, n)), this;
52
52
  };
53
- m.prototype.handle = function(o) {
53
+ p.prototype.handle = function(o) {
54
54
  let t, e;
55
55
  const n = o.type;
56
- let r, s, i, c, h = [], a;
56
+ let s, r, i, c, h = [], a;
57
57
  const d = "ftLabsDelegateIgnore";
58
58
  if (o[d] === !0)
59
59
  return;
60
- switch (a = o.target, a.nodeType === 3 && (a = a.parentNode), a.correspondingUseElement && (a = a.correspondingUseElement), r = this.rootElement, s = o.eventPhase || (o.target !== o.currentTarget ? 3 : 2), s) {
60
+ switch (a = o.target, a.nodeType === 3 && (a = a.parentNode), a.correspondingUseElement && (a = a.correspondingUseElement), s = this.rootElement, r = o.eventPhase || (o.target !== o.currentTarget ? 3 : 2), r) {
61
61
  case 1:
62
62
  h = this.listenerMap[1][n];
63
63
  break;
@@ -72,24 +72,24 @@ m.prototype.handle = function(o) {
72
72
  for (e = h.length; a && e; ) {
73
73
  for (t = 0; t < e && (i = h[t], !!i); t++)
74
74
  a.tagName && ["button", "input", "select", "textarea"].indexOf(a.tagName.toLowerCase()) > -1 && a.hasAttribute("disabled") ? u = [] : i.matcher.call(a, i.matcherParam, a) && u.push([o, a, i]);
75
- if (a === r || (e = h.length, a = a.parentElement || a.parentNode, a instanceof HTMLDocument))
75
+ if (a === s || (e = h.length, a = a.parentElement || a.parentNode, a instanceof HTMLDocument))
76
76
  break;
77
77
  }
78
- let E;
78
+ let b;
79
79
  for (t = 0; t < u.length; t++)
80
80
  if (!(this._removedListeners.indexOf(u[t][2]) > -1) && (c = this.fire.apply(this, u[t]), c === !1)) {
81
- u[t][0][d] = !0, u[t][0].preventDefault(), E = !1;
81
+ u[t][0][d] = !0, u[t][0].preventDefault(), b = !1;
82
82
  break;
83
83
  }
84
- return E;
84
+ return b;
85
85
  };
86
- m.prototype.fire = function(o, t, e) {
86
+ p.prototype.fire = function(o, t, e) {
87
87
  return e.handler.call(t, o, t);
88
88
  };
89
89
  function T(o, t) {
90
90
  return o.toLowerCase() === t.tagName.toLowerCase();
91
91
  }
92
- function S(o, t) {
92
+ function $(o, t) {
93
93
  return this.rootElement === window ? (
94
94
  // Match the outer document (dispatched from document)
95
95
  t === document || // The <html> element (dispatched from document.body or document.documentElement)
@@ -97,10 +97,10 @@ function S(o, t) {
97
97
  t === window
98
98
  ) : this.rootElement === t;
99
99
  }
100
- function $(o, t) {
100
+ function S(o, t) {
101
101
  return o === t.id;
102
102
  }
103
- m.prototype.destroy = function() {
103
+ p.prototype.destroy = function() {
104
104
  this.off(), this.root();
105
105
  };
106
106
  function y(o) {
@@ -110,7 +110,7 @@ function v(o, t) {
110
110
  for (const e in o)
111
111
  t[e] ? console.warn(`You can't set a custom property called ${e}`) : t[e] = o[e];
112
112
  }
113
- const p = Object.freeze({
113
+ const m = Object.freeze({
114
114
  DEBUG: 0,
115
115
  INFO: 1,
116
116
  WARN: 2,
@@ -118,35 +118,35 @@ const p = Object.freeze({
118
118
  TEST: 4,
119
119
  DEFAULT: 2
120
120
  });
121
- function N(o) {
121
+ function L(o) {
122
122
  const t = o == null ? void 0 : o.toLowerCase();
123
- return t === "debug" ? p.DEBUG : t === "info" ? p.INFO : t === "warn" ? p.WARN : t === "error" ? p.ERROR : t === "test" ? p.TEST : p.DEFAULT;
123
+ return t === "debug" ? m.DEBUG : t === "info" ? m.INFO : t === "warn" ? m.WARN : t === "error" ? m.ERROR : t === "test" ? m.TEST : m.DEFAULT;
124
124
  }
125
125
  class C {
126
- constructor({ level: t = p.DEFAULT } = {
127
- level: p.DEFAULT
126
+ constructor({ level: t = m.DEFAULT } = {
127
+ level: m.DEFAULT
128
128
  }) {
129
129
  this.log = this.debug, this.level = t;
130
130
  }
131
131
  debug(...t) {
132
- this.level <= p.DEBUG && console.info(...t);
132
+ this.level <= m.DEBUG && console.info(...t);
133
133
  }
134
134
  info(...t) {
135
- this.level <= p.INFO && console.info(...t);
135
+ this.level <= m.INFO && console.info(...t);
136
136
  }
137
137
  warn(...t) {
138
- this.level <= p.WARN && console.warn(...t);
138
+ this.level <= m.WARN && console.warn(...t);
139
139
  }
140
140
  error(...t) {
141
- this.level <= p.ERROR && console.error(...t);
141
+ this.level <= m.ERROR && console.error(...t);
142
142
  }
143
143
  }
144
- const L = (o, t, e) => {
145
- const n = Array.from((o == null ? void 0 : o.querySelectorAll(e)) ?? []), r = n.findIndex((s) => s === t);
146
- if (r !== -1)
144
+ const N = (o, t, e) => {
145
+ const n = Array.from((o == null ? void 0 : o.querySelectorAll(e)) ?? []), s = n.findIndex((r) => r === t);
146
+ if (s !== -1)
147
147
  return {
148
148
  siblings: n.length,
149
- position: r
149
+ position: s
150
150
  };
151
151
  }, k = [
152
152
  "nodeName",
@@ -178,25 +178,25 @@ const L = (o, t, e) => {
178
178
  t[e.name] = e.value;
179
179
  }), t), M = (o, t, e) => {
180
180
  const n = {};
181
- return e && k.forEach((r) => {
182
- typeof t[r] < "u" && r !== "id" && (n[r] = t[r]);
183
- }), o.filter((r) => r.name.match(/^data-trackable-context-/i)).forEach((r) => {
184
- n[r.name.replace("data-trackable-context-", "")] = x(r.value);
181
+ return e && k.forEach((s) => {
182
+ typeof t[s] < "u" && s !== "id" && (n[s] = t[s]);
183
+ }), o.filter((s) => s.name.match(/^data-trackable-context-/i)).forEach((s) => {
184
+ n[s.name.replace("data-trackable-context-", "")] = x(s.value);
185
185
  }), n;
186
186
  };
187
187
  function D(o, t) {
188
- const e = o, n = e != null && e.getAttribute("data-trackable") ? `[data-trackable="${e.getAttribute("data-trackable")}"]` : e == null ? void 0 : e.nodeName, r = [], s = {};
188
+ const e = o, n = e != null && e.getAttribute("data-trackable") ? `[data-trackable="${e.getAttribute("data-trackable")}"]` : e == null ? void 0 : e.nodeName, s = [], r = {};
189
189
  for (; o && o !== t; ) {
190
190
  const i = O(o), c = Array.from(o.attributes);
191
191
  let h = I(c, i);
192
192
  h["data-trackable"] && (h = Object.assign(
193
193
  h,
194
- L(o, e, n)
195
- )), r.push(h);
194
+ N(o, e, n)
195
+ )), s.push(h);
196
196
  const a = M(c, i, o === e);
197
- v(a, s), o = o.parentNode;
197
+ v(a, r), o = o.parentNode;
198
198
  }
199
- return { trace: r, customContext: s };
199
+ return { trace: s, customContext: r };
200
200
  }
201
201
  const U = ["ctrlKey", "altKey", "shiftKey", "metaKey"];
202
202
  class F {
@@ -204,13 +204,13 @@ class F {
204
204
  id: t = "00000000-0000-0000-0000-000000000000",
205
205
  name: e = "ccc-component",
206
206
  subtype: n = "interactive",
207
- teamName: r = "djd",
208
- shadowRoot: s = null,
207
+ teamName: s = "djd",
208
+ shadowRoot: r = null,
209
209
  category: i = "cta",
210
210
  elements: c = 'a, button, input, [role="button"]',
211
211
  logger: h
212
212
  }) {
213
- this.cccId = t, this.cccName = e, this.subtype = n, this.teamName = r, this.shadowRoot = s, this.category = i, this.elements = c, this.isInitialised = !1, this.log = h ?? new C();
213
+ this.cccId = t, this.cccName = e, this.subtype = n, this.teamName = s, this.shadowRoot = r, this.category = i, this.elements = c, this.isInitialised = !1, this.log = h ?? new C();
214
214
  }
215
215
  // Get properties for the event (as opposed to properties of the clicked element)
216
216
  getEventProperties(t) {
@@ -219,21 +219,21 @@ class F {
219
219
  if (t[n])
220
220
  try {
221
221
  e[n] = y(t[n]);
222
- } catch (r) {
223
- this.log.info(r);
222
+ } catch (s) {
223
+ this.log.info(s);
224
224
  }
225
225
  return e;
226
226
  }
227
227
  // Controller for handling click events
228
228
  handleClickEvent(t, e) {
229
- return (n, r) => {
230
- const s = this.getEventProperties(n), { trace: i, customContext: c } = D(r, e);
231
- s.custom = r.dataset && r.dataset.custom ? JSON.parse(r.dataset.custom) : null, s.domPathTokens = i, s.component = {
229
+ return (n, s) => {
230
+ const r = this.getEventProperties(n), { trace: i, customContext: c } = D(s, e);
231
+ r.custom = s.dataset && s.dataset.custom ? JSON.parse(s.dataset.custom) : null, r.domPathTokens = i, r.component = {
232
232
  id: this.cccId,
233
233
  name: this.cccName,
234
234
  type: "custom-code-component",
235
235
  subtype: this.subtype
236
- }, s.teamName = this.teamName, s.url = document.URL, v(c, s), s.method = "ftCustomAnalytics", t = { ...t, ...s }, document.body.dispatchEvent(
236
+ }, r.teamName = this.teamName, r.url = document.URL, v(c, r), r.method = "ftCustomAnalytics", t = { ...t, ...r }, document.body.dispatchEvent(
237
237
  new CustomEvent("oTracking.event", {
238
238
  detail: t,
239
239
  bubbles: !0,
@@ -272,11 +272,11 @@ class F {
272
272
  const n = {
273
273
  action: "click",
274
274
  category: this.category
275
- }, r = (e = this.shadowRoot) == null ? void 0 : e.querySelector("[data-component-root]");
276
- r && new m(r).on(
275
+ }, s = (e = this.shadowRoot) == null ? void 0 : e.querySelector("[data-component-root]");
276
+ s && new p(s).on(
277
277
  "click",
278
278
  this.elements,
279
- this.handleClickEvent(n, r),
279
+ this.handleClickEvent(n, s),
280
280
  !0
281
281
  );
282
282
  }
@@ -284,16 +284,16 @@ class F {
284
284
  }
285
285
  class l {
286
286
  constructor(t) {
287
- const { org: e, repo: n, component: r, versionRange: s } = w(
287
+ const { org: e, repo: n, component: s, versionRange: r } = w(
288
288
  t
289
289
  ) ? t : l.fromString(t);
290
- this.org = e, this.repo = n, this.component = r, this.versionRange = s;
290
+ this.org = e, this.repo = n, this.component = s, this.versionRange = r;
291
291
  }
292
292
  set path(t) {
293
- const { org: e, repo: n, component: r, versionRange: s } = w(
293
+ const { org: e, repo: n, component: s, versionRange: r } = w(
294
294
  t
295
295
  ) ? t : l.fromString(t);
296
- this.org = e, this.repo = n, this.component = r, this.versionRange = s;
296
+ this.org = e, this.repo = n, this.component = s, this.versionRange = r;
297
297
  }
298
298
  get path() {
299
299
  return `${this.org}/${this.repo}@${this.versionRange}/${this.component}`;
@@ -308,8 +308,8 @@ class l {
308
308
  const n = e ?? ((c = t.match(/@[^\/]+/)) == null ? void 0 : c.toString().replace("@", "")) ?? "unknown";
309
309
  if (!n)
310
310
  throw new f("No version specified");
311
- const [r, s, i] = t.replace(/@[^\/]+/, "").split("/").reverse();
312
- return new l({ org: i, repo: s, component: r, versionRange: n });
311
+ const [s, r, i] = t.replace(/@[^\/]+/, "").split("/").reverse();
312
+ return new l({ org: i, repo: r, component: s, versionRange: n });
313
313
  }
314
314
  }
315
315
  function w(o) {
@@ -317,8 +317,8 @@ function w(o) {
317
317
  }
318
318
  class f extends Error {
319
319
  constructor(t, e) {
320
- var n = (...r) => {
321
- super(...r);
320
+ var n = (...s) => {
321
+ super(...s);
322
322
  };
323
323
  !e && t ? (n(t), this.component = null) : typeof (e == null ? void 0 : e.component) == "string" ? (n(
324
324
  t ?? `${e.cause ?? "Unknown error"} in ${e.component} imported from ${e.source ?? "an undefined source"}.`
@@ -356,36 +356,36 @@ const _ = (o) => o.replace(
356
356
  (t, e) => (e ? "-" : "") + t.toLowerCase()
357
357
  );
358
358
  function V(o) {
359
- return b([
359
+ return E([
360
360
  "localhost",
361
361
  "local.ft.com",
362
362
  /^.*\.apps\.in\.ft\.com$/
363
363
  ], o);
364
364
  }
365
365
  function z() {
366
- return b([
366
+ return E([
367
367
  "localhost",
368
368
  "local.ft.com",
369
369
  /^.*\.in\.ft\.com$/
370
370
  ], window.location.hostname);
371
371
  }
372
372
  function J() {
373
- return b([
373
+ return E([
374
374
  "spark.ft.com",
375
375
  "spark-staging.ft.com"
376
376
  ], window.location.host);
377
377
  }
378
- function b(o, t) {
378
+ function E(o, t) {
379
379
  return t ? o.some((e) => typeof e == "string" ? e === t : e.test(t)) : !1;
380
380
  }
381
381
  function H(o) {
382
- if (!o)
382
+ if (o === null)
383
383
  return;
384
384
  let t;
385
385
  const e = new URL("http://localhost:5173");
386
386
  try {
387
387
  if (typeof o == "string") {
388
- if (o === "true" && z())
388
+ if ((o === "" || o.toLowerCase() === "true") && z())
389
389
  t = e;
390
390
  else if (t = o.startsWith("http://") || o.startsWith("https://") ? new URL(o) : void 0, t && !V(t == null ? void 0 : t.hostname))
391
391
  throw new Error("Unsafe testing host override");
@@ -401,16 +401,16 @@ async function K(o) {
401
401
  return !1;
402
402
  function t(n) {
403
403
  try {
404
- return new Promise((r) => {
405
- const s = new WebSocket(`ws://${n}`, "vite-hmr"), i = setTimeout(() => {
406
- r(s.readyState === WebSocket.OPEN), s.close();
404
+ return new Promise((s) => {
405
+ const r = new WebSocket(`ws://${n}`, "vite-hmr"), i = setTimeout(() => {
406
+ s(r.readyState === WebSocket.OPEN), r.close();
407
407
  }, 50);
408
- s.addEventListener("error", () => {
409
- clearTimeout(i), s.close(), r(!1);
408
+ r.addEventListener("error", () => {
409
+ clearTimeout(i), r.close(), s(!1);
410
410
  }, { once: !0 });
411
411
  });
412
- } catch (r) {
413
- return console.error("WebSocket creation failed:", r), Promise.resolve(!1);
412
+ } catch {
413
+ return Promise.resolve(!1);
414
414
  }
415
415
  }
416
416
  return await t(o == null ? void 0 : o.host);
@@ -427,25 +427,25 @@ class q extends HTMLElement {
427
427
  "env",
428
428
  "load-timeout"
429
429
  ]), this.channel = new MessageChannel(), this.initTracking = async () => {
430
- var r;
430
+ var s;
431
431
  try {
432
- (r = this.tracking) == null || r.init(this.id);
433
- } catch (s) {
432
+ (s = this.tracking) == null || s.init(this.id);
433
+ } catch (r) {
434
434
  const i = this.getAttribute("path"), c = this.getAttribute("version");
435
435
  this.log.info(
436
436
  `Error initialising tracking on <custom-code-component> ${i}@${c}`
437
- ), this.log.error(s);
437
+ ), this.log.error(r);
438
438
  }
439
439
  }, this.log = new C({
440
- level: N(this.getAttribute("log"))
440
+ level: L(this.getAttribute("log"))
441
441
  });
442
442
  const t = this.getAttribute("path"), e = this.getAttribute("version");
443
443
  this.component = l.fromString(t, e), this.lightRoot = Array.from(this.childNodes);
444
444
  const n = HTMLElement.prototype.hasOwnProperty("attachInternals");
445
445
  try {
446
- const r = n && this.attachInternals();
447
- } catch (r) {
448
- this.log.error(r);
446
+ const s = n && this.attachInternals();
447
+ } catch (s) {
448
+ this.log.error(s);
449
449
  }
450
450
  }
451
451
  async connectedCallback() {
@@ -499,7 +499,7 @@ class q extends HTMLElement {
499
499
  })
500
500
  ), this.dataset.cccReady = "true", delete this.dataset.cccError, !this.app)
501
501
  throw new Error("CCC mounted without App");
502
- const e = this.shadowRoot !== null, n = this.shadowRoot ?? this.attachShadow({ mode: this.mode }), r = JSON.parse(this.getAttribute("data-component-props")), s = Object.fromEntries(
502
+ const e = this.shadowRoot !== null, n = this.shadowRoot ?? this.attachShadow({ mode: this.mode }), s = JSON.parse(this.getAttribute("data-component-props")), r = Object.fromEntries(
503
503
  [...this.attributes].filter((a) => !this.RESERVED_ATTRS.has(a.name)).map((a) => [a.name, a.value])
504
504
  );
505
505
  this.tracking = new F({
@@ -512,8 +512,8 @@ class q extends HTMLElement {
512
512
  const { unmount: i, onmessage: c, ready: h } = this.app(
513
513
  n,
514
514
  {
515
- ...s,
516
- data: r,
515
+ ...r,
516
+ data: s,
517
517
  port: this.channel.port2,
518
518
  tracking: this.tracking,
519
519
  prerendered: !!t,
@@ -535,8 +535,8 @@ class q extends HTMLElement {
535
535
  this.onunmount(), (e = this.shadowRoot) == null || e.replaceChildren(...this.lightRoot), this.dataset.cccError || (this.dataset.cccError = _(t.name.replace("CCC", ""))), delete this.dataset.cccReady;
536
536
  }
537
537
  async load() {
538
- const t = this.getAttribute("path"), e = this.getAttribute("version"), n = Number(this.getAttribute("load-timeout") || 1e4), r = this.getAttribute("testEnv"), s = H(r), i = await K(s), c = this.getAttribute("id");
539
- this.source = i ? `${s == null ? void 0 : s.origin}/src/${this.component.component}/index.jsx?id=${c}` : `https://www.ft.com/__component/${this.component.org}/${this.component.repo}${e ? `@${e}` : "@latest"}/${this.component.component}/${this.component.component}.js?id=${c}`;
538
+ const t = this.getAttribute("path"), e = this.getAttribute("version"), n = Number(this.getAttribute("load-timeout") || 1e4), s = this.getAttribute("testEnv"), r = H(s), i = await K(r), c = this.getAttribute("id");
539
+ this.source = i ? `${r == null ? void 0 : r.origin}/src/${this.component.component}/index.jsx?id=${c}` : `https://www.ft.com/__component/${this.component.org}/${this.component.repo}${e ? `@${e}` : "@latest"}/${this.component.component}/${this.component.component}.js?id=${c}`;
540
540
  try {
541
541
  return await new Promise(
542
542
  (h, a) => {
@@ -586,6 +586,8 @@ class q extends HTMLElement {
586
586
  }
587
587
  }
588
588
  }
589
+ const B = () => customElements.define("custom-code-component", q);
590
+ customElements && !customElements.get("custom-code-component") && B();
589
591
  export {
590
- q as FTCustomCodeComponent
592
+ B as init
591
593
  };
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "@financial-times/custom-code-component",
3
- "version": "2.0.1-alpha.6",
3
+ "version": "2.0.1-alpha.8",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {
7
- "import": "./dist/custom-code-component.js",
7
+ "default": "./dist/custom-code-component.js",
8
8
  "types": "./dist/custom-code-component.d.ts"
9
9
  }
10
10
  },
@@ -8,15 +8,16 @@ import { isLocalEnv, isSafeTestEnv, isSparkEnv } from "./util"
8
8
  * @returns A `URL` object if valid and safe, or `undefined` if invalid.
9
9
  */
10
10
  export function assignTestURL(testEnv: string | null): URL | undefined {
11
- if (!testEnv) {
11
+ if (testEnv === null) {
12
12
  return
13
13
  }
14
+
14
15
  let testUrl
15
16
  const defaultTestUrl = new URL('http://localhost:5173')
16
17
 
17
18
  try {
18
19
  if (typeof testEnv === 'string') {
19
- if (testEnv === 'true' && isLocalEnv()) {
20
+ if ((testEnv === '' || testEnv.toLowerCase() === 'true') && isLocalEnv()) {
20
21
  testUrl = defaultTestUrl
21
22
  } else {
22
23
  const hasProtocol = testEnv.startsWith('http://') || testEnv.startsWith('https://')
@@ -66,7 +67,6 @@ export async function useComponentTestEnv(testUrl?: URL): Promise<boolean> {
66
67
  }, { once: true });
67
68
  });
68
69
  } catch (err) {
69
- console.error("WebSocket creation failed:", err);
70
70
  return Promise.resolve(false);
71
71
  }
72
72
  }