@flux-ui/statistics 3.0.0-next.71 → 3.0.0-next.73

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/index.js CHANGED
@@ -130,13 +130,39 @@ function deepResolveCssVars(value, root) {
130
130
  return changed ? out : value;
131
131
  }
132
132
  //#endregion
133
+ //#region src/util/html.ts
134
+ var HTML_ESCAPES = {
135
+ "&": "&",
136
+ "<": "&lt;",
137
+ ">": "&gt;",
138
+ "\"": "&quot;",
139
+ "'": "&#39;"
140
+ };
141
+ var HTML_PATTERN = /[&<>"']/g;
142
+ var ATTR_PATTERN = /[&<>"]/g;
143
+ /**
144
+ * Escapes a value for safe interpolation into HTML text content.
145
+ */
146
+ function escapeHtml(value) {
147
+ return String(value ?? "").replace(HTML_PATTERN, (char) => HTML_ESCAPES[char]);
148
+ }
149
+ /**
150
+ * Escapes a value for safe interpolation into a double-quoted HTML attribute
151
+ * or inline style value. Prevents attribute breakout from untrusted input.
152
+ */
153
+ function escapeAttr(value) {
154
+ return String(value ?? "").replace(ATTR_PATTERN, (char) => HTML_ESCAPES[char]);
155
+ }
156
+ //#endregion
133
157
  //#region src/util/icons.ts
134
158
  function renderIconSvg(name, color, size = 14) {
135
159
  if (!name) return "";
136
160
  const icon = iconRegistry[name];
137
161
  if (!icon) return "";
138
162
  const [width, height, , , pathData] = icon;
139
- return `<svg viewBox="0 0 ${width} ${height}" width="${size}" height="${size}" focusable="false" aria-hidden="true">${(Array.isArray(pathData) ? pathData : [pathData]).map((d) => `<path d="${d}" fill="${color}"/>`).join("")}</svg>`;
163
+ const paths = Array.isArray(pathData) ? pathData : [pathData];
164
+ const safeColor = escapeAttr(color);
165
+ return `<svg viewBox="0 0 ${width} ${height}" width="${size}" height="${size}" focusable="false" aria-hidden="true">${paths.map((d) => `<path d="${escapeAttr(d)}" fill="${safeColor}"/>`).join("")}</svg>`;
140
166
  }
141
167
  //#endregion
142
168
  //#region src/util/series/chartColors.ts
@@ -6782,7 +6808,7 @@ function friendlyDateTime(dateTimeish) {
6782
6808
  else throw new InvalidArgumentError(`Unknown datetime argument: ${dateTimeish}, of type ${typeof dateTimeish}`);
6783
6809
  }
6784
6810
  //#endregion
6785
- //#region ../../node_modules/.bun/@basmilius+utils@3.35.0+f2ed1ec6a4c7f7fd/node_modules/@basmilius/utils/dist/index.mjs
6811
+ //#region ../../node_modules/.bun/@basmilius+utils@3.37.0+f2ed1ec6a4c7f7fd/node_modules/@basmilius/utils/dist/index.mjs
6786
6812
  function p$2(e, t = 0) {
6787
6813
  let n = typeof navigator < `u` ? navigator.language : `nl-NL`;
6788
6814
  return new Intl.NumberFormat(n, {
@@ -6822,17 +6848,18 @@ function K(e, t, n) {
6822
6848
  //#region src/util/tooltips/render.ts
6823
6849
  function renderTooltip(t, styles, title, items, activeIndex = -1, valueFormatter) {
6824
6850
  if (items.length === 0) return "";
6825
- const titleHtml = title ? `<div class="${styles.statisticsChartTooltipTitle}">${title}</div>` : "";
6851
+ const titleHtml = title ? `<div class="${styles.statisticsChartTooltipTitle}">${escapeHtml(title)}</div>` : "";
6826
6852
  const hasActive = activeIndex !== -1;
6827
6853
  const body = items.map((item, idx) => {
6828
6854
  const activeClass = !hasActive || idx === activeIndex ? ` ${styles.isActive}` : "";
6829
6855
  const translatedName = item.name ? t(String(item.name)) : "";
6830
- const marker = item.icon ? `<div class="${styles.statisticsChartTooltipSeriesIcon}${activeClass}" style="color: ${item.color}">${renderIconSvg(item.icon, item.color, 14)}</div>` : `<div class="${styles.statisticsChartTooltipSeriesColor}${activeClass}" style="background: ${item.color}"></div>`;
6856
+ const safeColor = escapeAttr(item.color);
6857
+ const marker = item.icon ? `<div class="${styles.statisticsChartTooltipSeriesIcon}${activeClass}" style="color: ${safeColor}">${renderIconSvg(item.icon, item.color, 14)}</div>` : `<div class="${styles.statisticsChartTooltipSeriesColor}${activeClass}" style="background: ${safeColor}"></div>`;
6831
6858
  const display = valueFormatter ? valueFormatter(item.value, item) : formatValue(item.value);
6832
6859
  return `
6833
6860
  ${marker}
6834
- <div class="${styles.statisticsChartTooltipSeriesName}${activeClass}">${translatedName}</div>
6835
- <div class="${styles.statisticsChartTooltipSeriesValue}${activeClass}">${display}</div>
6861
+ <div class="${styles.statisticsChartTooltipSeriesName}${activeClass}">${escapeHtml(translatedName)}</div>
6862
+ <div class="${styles.statisticsChartTooltipSeriesValue}${activeClass}">${escapeHtml(display)}</div>
6836
6863
  `;
6837
6864
  }).join("");
6838
6865
  return `<div class="${styles.statisticsChartTooltip}">${titleHtml}<div class="${styles.statisticsChartTooltipBody}">${body}</div></div>`;
@@ -10740,7 +10767,7 @@ useMode(definition$2);
10740
10767
  useMode(definition$1);
10741
10768
  useMode(definition);
10742
10769
  //#endregion
10743
- //#region ../../node_modules/.bun/@basmilius+http-client@3.35.0+f97c77f67c914c00/node_modules/@basmilius/http-client/dist/index.mjs
10770
+ //#region ../../node_modules/.bun/@basmilius+http-client@3.37.0+f97c77f67c914c00/node_modules/@basmilius/http-client/dist/index.mjs
10744
10771
  function adapter_default(Parent) {
10745
10772
  return class extends Parent {
10746
10773
  constructor(...args) {
@@ -10748,6 +10775,11 @@ function adapter_default(Parent) {
10748
10775
  }
10749
10776
  };
10750
10777
  }
10778
+ function bound_default() {
10779
+ return (target, method) => {
10780
+ target[method] = target[method].bind(target);
10781
+ };
10782
+ }
10751
10783
  /**
10752
10784
  * Checks if the two given values are equal. When both values are a
10753
10785
  * dto, the check is done by firstly converthing them to JSON.
@@ -10771,7 +10803,7 @@ var TRIGGER = Symbol();
10771
10803
  * Checks if the given object is a dto.
10772
10804
  */
10773
10805
  function isDto_default(obj) {
10774
- return obj && typeof obj === "object" && !!obj[NAME];
10806
+ return typeof obj === "object" && obj !== null && NAME in obj;
10775
10807
  }
10776
10808
  /**
10777
10809
  * Asserts that the given object is a dto.
@@ -10826,6 +10858,9 @@ var markDtoClean = circularProtect_default(function(obj) {
10826
10858
  if (!obj[CHILDREN] || obj[CHILDREN].length === 0) return;
10827
10859
  obj[CHILDREN].filter(isDtoDirty_default).forEach(markDtoClean);
10828
10860
  });
10861
+ function isProxiedArray_default(value) {
10862
+ return Array.isArray(value) && PARENT in value;
10863
+ }
10829
10864
  /**
10830
10865
  * Marks the given dto dirty.
10831
10866
  */
@@ -10852,7 +10887,7 @@ function relateDtoTo_default(dto, parent, key) {
10852
10887
  */
10853
10888
  function relateValueTo_default(dto, key, value) {
10854
10889
  if (isDto_default(value)) relateDtoTo_default(value, dto, key);
10855
- else if (Array.isArray(value)) {
10890
+ else if (isProxiedArray_default(value)) {
10856
10891
  for (const item of value) {
10857
10892
  if (!isDto_default(item)) continue;
10858
10893
  relateDtoTo_default(item, dto, key);
@@ -10884,7 +10919,7 @@ function unrelateDtoFrom_default(dto, parent) {
10884
10919
  */
10885
10920
  function unrelateValueFrom_default(dto, value) {
10886
10921
  if (isDto_default(value)) unrelateDtoFrom_default(value, dto);
10887
- else if (Array.isArray(value)) {
10922
+ else if (isProxiedArray_default(value)) {
10888
10923
  for (const item of value) if (isDto_default(item)) unrelateDtoFrom_default(item, dto);
10889
10924
  value[PARENT] = void 0;
10890
10925
  value[PARENT_KEY] = void 0;
@@ -10928,7 +10963,7 @@ var arrayProxy_default = {
10928
10963
  }
10929
10964
  };
10930
10965
  /**
10931
- * Checks if the given key should be ignored by the proxy.
10966
+ * Checks if the proxy should ignore the given key.
10932
10967
  */
10933
10968
  function ignored(target, key) {
10934
10969
  return typeof key === "symbol" || typeof target[key] === "function" || key === "length";
@@ -10973,7 +11008,7 @@ var instanceProxy_default = {
10973
11008
  const oldValue = descriptor.get?.call(target) ?? void 0;
10974
11009
  if (areEqual_default(value, oldValue)) return true;
10975
11010
  unrelateValueFrom_default(target, oldValue);
10976
- if (Array.isArray(value) && !value[PROXY]) value = new Proxy(value, arrayProxy_default);
11011
+ if (Array.isArray(value) && !isProxiedArray_default(value)) value = new Proxy(value, arrayProxy_default);
10977
11012
  descriptor.set.call(target, value);
10978
11013
  relateValueTo_default(target, key, value);
10979
11014
  markDtoDirty(target, key);
@@ -11097,7 +11132,7 @@ function dto_default(clazz) {
11097
11132
  K(clazz.prototype, DESCRIPTORS, descriptors);
11098
11133
  K(clazz.prototype, NAME, clazz.name);
11099
11134
  K(clazz.prototype, PROPERTIES, properties);
11100
- K(clazz, Symbol.hasInstance, (instance) => typeof instance === "object" && instance?.[NAME] === clazz.name);
11135
+ K(clazz, Symbol.hasInstance, (instance) => typeof instance === "object" && instance !== null && NAME in instance && instance[NAME] === clazz.name);
11101
11136
  G$1(clazz, "clone", clone_default);
11102
11137
  G$1(clazz, "fill", fill_default);
11103
11138
  G$1(clazz, "toJSON", toJSON_default);
@@ -11118,6 +11153,12 @@ function __decorate(decorators, target, key, desc) {
11118
11153
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
11119
11154
  return c > 3 && r && Object.defineProperty(target, key, r), r;
11120
11155
  }
11156
+ var X = class {
11157
+ test() {
11158
+ return true;
11159
+ }
11160
+ };
11161
+ __decorate([bound_default()], X.prototype, "test", null);
11121
11162
  var BlobResponse = class BlobResponse {
11122
11163
  get blob() {
11123
11164
  return this.#blob;
@@ -11230,7 +11271,7 @@ var HttpAdapter = _HttpAdapter = class HttpAdapter {
11230
11271
  const defaultFilename = `download-${DateTime.now().toFormat("yyyy-MM-dd HH-mm-ss")}`;
11231
11272
  if (!header.startsWith("attachment")) return defaultFilename;
11232
11273
  const matches = /filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/.exec(header);
11233
- if ((matches?.length || 0) < 2) return defaultFilename;
11274
+ if (!matches || matches.length < 2) return defaultFilename;
11234
11275
  return matches[1].replaceAll("'", "").replaceAll("\"", "").replaceAll("/", "-").replaceAll(":", "-");
11235
11276
  }
11236
11277
  static parseRequestError(data, statusCode) {
@@ -11238,12 +11279,7 @@ var HttpAdapter = _HttpAdapter = class HttpAdapter {
11238
11279
  }
11239
11280
  static parseValidationError(data) {
11240
11281
  let errors;
11241
- if (data.errors) {
11242
- errors = {};
11243
- Object.entries(data.errors).forEach(([key, value]) => {
11244
- errors[key] = _HttpAdapter.parseValidationError(value);
11245
- });
11246
- }
11282
+ if (data.errors) errors = Object.fromEntries(Object.entries(data.errors).map(([key, value]) => [key, _HttpAdapter.parseValidationError(value)]));
11247
11283
  return new ValidationError_default(data.code, data.error, data.error_description, errors, data.params);
11248
11284
  }
11249
11285
  };