@01.software/sdk 0.5.3 → 0.5.4

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/ui/flow.js CHANGED
@@ -420,6 +420,7 @@ function ensureQuickJSLoaded() {
420
420
  _notify();
421
421
  }).catch(() => {
422
422
  _state = { status: "failed", module: null };
423
+ _notify();
423
424
  });
424
425
  }
425
426
  function useQuickJS() {
@@ -564,7 +565,11 @@ function sanitizeStyle(style) {
564
565
  for (const [k, v] of Object.entries(style)) {
565
566
  if (BLOCKED_STYLE_PROPS.has(k)) continue;
566
567
  if (typeof v === "string" && /url\s*\(/i.test(v)) continue;
567
- if (k === "position" && typeof v === "string" && /fixed|absolute/i.test(v)) continue;
568
+ if (k === "position" && typeof v === "string" && /fixed|sticky/i.test(v)) continue;
569
+ if (k === "zIndex") {
570
+ const n = typeof v === "number" ? v : parseInt(String(v), 10);
571
+ if (isNaN(n) || n > 9998) continue;
572
+ }
568
573
  safe[k] = v;
569
574
  }
570
575
  return safe;
@@ -660,10 +665,10 @@ function compileTemplate(code, slug) {
660
665
  if (!qjs) return null;
661
666
  const cacheKey = `${slug}:${code.length}:${hashCode(code)}`;
662
667
  if (rendererCache.has(cacheKey)) {
663
- const renderer2 = rendererCache.get(cacheKey);
668
+ const entry = rendererCache.get(cacheKey);
664
669
  rendererCache.delete(cacheKey);
665
- rendererCache.set(cacheKey, renderer2);
666
- return makeReactFC(renderer2, qjs);
670
+ rendererCache.set(cacheKey, entry);
671
+ return entry.fc;
667
672
  }
668
673
  let jsCode;
669
674
  try {
@@ -678,12 +683,13 @@ function compileTemplate(code, slug) {
678
683
  return null;
679
684
  }
680
685
  const renderer = makeRenderer(jsCode);
686
+ const fc = makeReactFC(renderer, qjs);
681
687
  if (rendererCache.size >= MAX_CACHE_SIZE) {
682
688
  const oldest = rendererCache.keys().next().value;
683
689
  if (oldest) rendererCache.delete(oldest);
684
690
  }
685
- rendererCache.set(cacheKey, renderer);
686
- return makeReactFC(renderer, qjs);
691
+ rendererCache.set(cacheKey, { renderer, fc });
692
+ return fc;
687
693
  }
688
694
  function clearTemplateCache() {
689
695
  rendererCache.clear();
@@ -880,6 +886,11 @@ import postcss from "postcss";
880
886
  var ALLOWED_AT_RULES = /* @__PURE__ */ new Set(["keyframes", "media", "supports", "container", "layer"]);
881
887
  var BLOCKED_VALUE_PATTERNS = [/url\s*\(/i, /expression\s*\(/i, /paint\s*\(/i, /-moz-binding/i];
882
888
  var DANGEROUS_SELECTOR = /(?:^|[\s,])(?::root|html|body)\b/;
889
+ var BLOCKED_PROPERTY_VALUES = {
890
+ // absolute is allowed — contained by nearest positioned ancestor (node wrapper)
891
+ position: /fixed|sticky/i
892
+ };
893
+ var Z_INDEX_MAX = 9998;
883
894
  function sanitizeCSS(css, scopeClass) {
884
895
  let root;
885
896
  try {
@@ -887,14 +898,66 @@ function sanitizeCSS(css, scopeClass) {
887
898
  } catch (e) {
888
899
  return "";
889
900
  }
901
+ const safeScopeClass = scopeClass ? scopeClass.replace(/[{}()[\];,'"\\<>\s]/g, "") : "";
902
+ const keyframeNameMap = /* @__PURE__ */ new Map();
903
+ if (safeScopeClass) {
904
+ root.walkAtRules(/^keyframes$/i, (node) => {
905
+ const rawName = node.params.trim().replace(/^['"]|['"]$/g, "");
906
+ const originalName = rawName;
907
+ const scopedName = `${safeScopeClass}__${rawName.replace(/\s+/g, "_")}`;
908
+ keyframeNameMap.set(originalName, scopedName);
909
+ node.params = scopedName;
910
+ });
911
+ }
912
+ if (safeScopeClass && keyframeNameMap.size > 0) {
913
+ const ANIM_KEYWORDS = /* @__PURE__ */ new Set(["none", "initial", "inherit", "unset", "revert"]);
914
+ const replaceAnimName = (token) => {
915
+ var _a;
916
+ const t = token.trim().replace(/^['"]|['"]$/g, "");
917
+ return ANIM_KEYWORDS.has(t) ? token : (_a = keyframeNameMap.get(t)) != null ? _a : token;
918
+ };
919
+ root.walkDecls(/^animation-name$/i, (node) => {
920
+ node.value = node.value.split(",").map(replaceAnimName).join(", ");
921
+ });
922
+ root.walkDecls(/^animation$/i, (node) => {
923
+ node.value = node.value.split(",").map(
924
+ (anim) => anim.split(/(\s+)/).map((token) => /\s/.test(token) ? token : replaceAnimName(token)).join("")
925
+ ).join(",");
926
+ });
927
+ }
890
928
  root.walkAtRules((node) => {
891
929
  if (!ALLOWED_AT_RULES.has(node.name.toLowerCase())) {
892
930
  node.remove();
893
931
  }
894
932
  });
895
933
  root.walkDecls((node) => {
896
- if (BLOCKED_VALUE_PATTERNS.some((p) => p.test(node.value))) {
934
+ const normalizedValue = node.value.replace(/\/\*[\s\S]*?\*\//g, "");
935
+ if (BLOCKED_VALUE_PATTERNS.some((p) => p.test(normalizedValue))) {
897
936
  node.remove();
937
+ return;
938
+ }
939
+ const propLower = node.prop.toLowerCase();
940
+ const blockedValuePattern = BLOCKED_PROPERTY_VALUES[propLower];
941
+ if (blockedValuePattern) {
942
+ const deescaped = normalizedValue.replace(
943
+ /\\([0-9a-fA-F]{1,6})\s?/g,
944
+ (_, hex) => String.fromCodePoint(parseInt(hex, 16))
945
+ );
946
+ if (blockedValuePattern.test(deescaped)) {
947
+ node.remove();
948
+ return;
949
+ }
950
+ }
951
+ if (propLower === "z-index") {
952
+ const zv = node.value.trim();
953
+ if (zv === "auto" || zv === "initial" || zv === "inherit" || zv === "unset" || zv === "revert") {
954
+ } else {
955
+ const val = parseInt(zv, 10);
956
+ if (isNaN(val) || String(val) !== zv || val > Z_INDEX_MAX) {
957
+ node.remove();
958
+ return;
959
+ }
960
+ }
898
961
  }
899
962
  });
900
963
  root.walkRules((rule) => {
@@ -904,7 +967,6 @@ function sanitizeCSS(css, scopeClass) {
904
967
  return;
905
968
  }
906
969
  if (scopeClass) {
907
- const safeScopeClass = scopeClass.replace(/[{}()[\];,'"\\<>]/g, "");
908
970
  if (!safeScopeClass) {
909
971
  rule.remove();
910
972
  return;