@getforma/core 1.0.9 → 1.1.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.
Files changed (64) hide show
  1. package/README.md +1 -1
  2. package/dist/chunk-263HW3KN.cjs +35 -0
  3. package/dist/chunk-263HW3KN.cjs.map +1 -0
  4. package/dist/chunk-2QQBKQIF.js +30 -0
  5. package/dist/chunk-2QQBKQIF.js.map +1 -0
  6. package/dist/{chunk-6FW5E54W.cjs → chunk-2Y5US35K.cjs} +127 -103
  7. package/dist/chunk-2Y5US35K.cjs.map +1 -0
  8. package/dist/{chunk-3G7ET4O5.js → chunk-INNOI6TG.js} +121 -94
  9. package/dist/chunk-INNOI6TG.js.map +1 -0
  10. package/dist/{chunk-T33QUD2Y.cjs → chunk-JRQNDXX7.cjs} +43 -43
  11. package/dist/{chunk-T33QUD2Y.cjs.map → chunk-JRQNDXX7.cjs.map} +1 -1
  12. package/dist/{chunk-AFRFF7XL.js → chunk-MIOMT2CB.js} +4 -4
  13. package/dist/{chunk-AFRFF7XL.js.map → chunk-MIOMT2CB.js.map} +1 -1
  14. package/dist/chunk-W7OUWVRA.cjs +106 -0
  15. package/dist/chunk-W7OUWVRA.cjs.map +1 -0
  16. package/dist/chunk-XLVBYXOU.js +100 -0
  17. package/dist/chunk-XLVBYXOU.js.map +1 -0
  18. package/dist/forma-runtime-csp.js +92 -6
  19. package/dist/forma-runtime.js +138 -12
  20. package/dist/formajs-runtime-hardened.global.js +92 -6
  21. package/dist/formajs-runtime-hardened.global.js.map +1 -1
  22. package/dist/formajs-runtime.global.js +138 -12
  23. package/dist/formajs-runtime.global.js.map +1 -1
  24. package/dist/formajs.global.js +192 -95
  25. package/dist/formajs.global.js.map +1 -1
  26. package/dist/http.cjs +11 -11
  27. package/dist/http.js +2 -2
  28. package/dist/index.cjs +66 -66
  29. package/dist/index.d.cts +11 -25
  30. package/dist/index.d.ts +11 -25
  31. package/dist/index.js +6 -6
  32. package/dist/{resource-DeEzxUz6.d.cts → resource-D6HfVgiA.d.cts} +7 -2
  33. package/dist/{resource-BHsgURy0.d.ts → resource-ljs2X5NM.d.ts} +7 -2
  34. package/dist/runtime-hardened.cjs +93 -5
  35. package/dist/runtime-hardened.cjs.map +1 -1
  36. package/dist/runtime-hardened.js +93 -5
  37. package/dist/runtime-hardened.js.map +1 -1
  38. package/dist/runtime.cjs +47 -31
  39. package/dist/runtime.cjs.map +1 -1
  40. package/dist/runtime.js +21 -5
  41. package/dist/runtime.js.map +1 -1
  42. package/dist/server.cjs +7 -7
  43. package/dist/server.d.cts +2 -2
  44. package/dist/server.d.ts +2 -2
  45. package/dist/server.js +2 -2
  46. package/dist/{signal-C9v4akyJ.d.cts → signal-CRBJYQ6B.d.cts} +0 -8
  47. package/dist/{signal-C9v4akyJ.d.ts → signal-CRBJYQ6B.d.ts} +0 -8
  48. package/dist/ssr/index.cjs +23 -42
  49. package/dist/ssr/index.cjs.map +1 -1
  50. package/dist/ssr/index.js +23 -42
  51. package/dist/ssr/index.js.map +1 -1
  52. package/dist/tc39-compat.cjs +3 -6
  53. package/dist/tc39-compat.cjs.map +1 -1
  54. package/dist/tc39-compat.d.cts +1 -1
  55. package/dist/tc39-compat.d.ts +1 -1
  56. package/dist/tc39-compat.js +1 -4
  57. package/dist/tc39-compat.js.map +1 -1
  58. package/package.json +2 -2
  59. package/dist/chunk-3G7ET4O5.js.map +0 -1
  60. package/dist/chunk-6FW5E54W.cjs.map +0 -1
  61. package/dist/chunk-HLM5BZZQ.js +0 -35
  62. package/dist/chunk-HLM5BZZQ.js.map +0 -1
  63. package/dist/chunk-QLPCVK7C.cjs +0 -38
  64. package/dist/chunk-QLPCVK7C.cjs.map +0 -1
@@ -438,11 +438,32 @@ var FormaRuntime = (function (exports) {
438
438
  }
439
439
  }
440
440
 
441
- // src/reactive/signal.ts
441
+ // src/reactive/dev.ts
442
+ function isDev() {
443
+ if (typeof process !== "undefined") {
444
+ return process.env?.NODE_ENV !== "production";
445
+ }
446
+ return typeof __FORMA_DEV__ !== "undefined" ? !!__FORMA_DEV__ : false;
447
+ }
448
+ isDev();
449
+ var _errorHandlers = /* @__PURE__ */ new Set();
450
+ function reportError(error, source) {
451
+ for (const handler of _errorHandlers) {
452
+ try {
453
+ handler(error, source ? { source } : {});
454
+ } catch {
455
+ }
456
+ }
457
+ if (isDev()) {
458
+ console.error(`[forma] ${source} error:`, error);
459
+ }
460
+ }
442
461
  function applySignalSet(s, v, equals) {
443
462
  if (typeof v !== "function") {
444
- s(v);
445
- return;
463
+ {
464
+ s(v);
465
+ return;
466
+ }
446
467
  }
447
468
  const prevSub = setActiveSub(void 0);
448
469
  const prev = s();
@@ -462,8 +483,35 @@ var FormaRuntime = (function (exports) {
462
483
  }
463
484
 
464
485
  // src/reactive/computed.ts
486
+ var ERR = /* @__PURE__ */ Symbol("formaComputedError");
487
+ function isErrBox(v) {
488
+ return typeof v === "object" && v !== null && ERR in v;
489
+ }
465
490
  function createComputed(fn) {
466
- return computed(fn);
491
+ let errored = false;
492
+ let error;
493
+ let lastGood;
494
+ const raw = computed(() => {
495
+ try {
496
+ const v = fn(lastGood);
497
+ errored = false;
498
+ error = void 0;
499
+ lastGood = v;
500
+ return v;
501
+ } catch (e) {
502
+ errored = true;
503
+ error = e;
504
+ reportError(e, "computed");
505
+ return { [ERR]: e };
506
+ }
507
+ });
508
+ const reader = () => {
509
+ const v = raw();
510
+ if (errored || isErrBox(v)) throw error;
511
+ return v;
512
+ };
513
+ Object.defineProperty(reader, "name", { value: raw.name, configurable: true });
514
+ return reader;
467
515
  }
468
516
 
469
517
  // src/reactive/batch.ts
@@ -1047,7 +1095,35 @@ var FormaRuntime = (function (exports) {
1047
1095
  };
1048
1096
  }
1049
1097
 
1098
+ // src/security/url-safety.ts
1099
+ var URL_IGNORED_CHARS_RE = /[\u0000-\u0020\u007F-\u009F]/g;
1100
+ var DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\/html)/i;
1101
+ var URL_ATTRS = /* @__PURE__ */ new Set([
1102
+ "href",
1103
+ "src",
1104
+ "action",
1105
+ "formaction",
1106
+ "xlink:href",
1107
+ "poster",
1108
+ "background"
1109
+ ]);
1110
+ function isUrlAttr(name) {
1111
+ return URL_ATTRS.has(name.toLowerCase());
1112
+ }
1113
+ function isDangerousUrl(value2) {
1114
+ const normalized = value2.replace(URL_IGNORED_CHARS_RE, "");
1115
+ return DANGEROUS_SCHEME_RE.test(normalized);
1116
+ }
1117
+ function isEventHandlerAttr(name) {
1118
+ return /^on/i.test(name);
1119
+ }
1120
+
1050
1121
  // src/runtime.ts
1122
+ function isUnsafeAttrBinding(name, value2) {
1123
+ if (isEventHandlerAttr(name)) return true;
1124
+ if (isUrlAttr(name) && isDangerousUrl(value2)) return true;
1125
+ return false;
1126
+ }
1051
1127
  var _refetchRegistry = /* @__PURE__ */ new Map();
1052
1128
  function $refetch(id) {
1053
1129
  const fn = _refetchRegistry.get(id);
@@ -2012,7 +2088,12 @@ var FormaRuntime = (function (exports) {
2012
2088
  if (attr.value.includes("{item")) {
2013
2089
  const compiled = compileTemplate(attr.value);
2014
2090
  entries.push({ attr: attr.name, compiled });
2015
- node.setAttribute(attr.name, evaluateCompiledTemplate(compiled, item));
2091
+ const value2 = evaluateCompiledTemplate(compiled, item);
2092
+ if (isUnsafeAttrBinding(attr.name, value2)) {
2093
+ node.removeAttribute(attr.name);
2094
+ } else {
2095
+ node.setAttribute(attr.name, value2);
2096
+ }
2016
2097
  }
2017
2098
  }
2018
2099
  if (entries.length > 0) {
@@ -2784,7 +2865,12 @@ var FormaRuntime = (function (exports) {
2784
2865
  if (val == null || val === false) {
2785
2866
  el.removeAttribute(attrName);
2786
2867
  } else {
2787
- el.setAttribute(attrName, String(val));
2868
+ const str = String(val);
2869
+ if (isUnsafeAttrBinding(attrName, str)) {
2870
+ el.removeAttribute(attrName);
2871
+ } else {
2872
+ el.setAttribute(attrName, str);
2873
+ }
2788
2874
  }
2789
2875
  });
2790
2876
  disposers.push(dispose);