@hyperframes/parsers 0.7.46 → 0.7.48

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
@@ -1936,6 +1936,46 @@ function parseGsapScriptAcorn(script) {
1936
1936
  }
1937
1937
  }
1938
1938
 
1939
+ // src/compositionVariables.ts
1940
+ var DEFAULT_TYPEOF = {
1941
+ string: "string",
1942
+ number: "number",
1943
+ color: "string",
1944
+ boolean: "boolean",
1945
+ enum: "string",
1946
+ font: "string",
1947
+ image: "string"
1948
+ };
1949
+ function isRecord(v) {
1950
+ return typeof v === "object" && v !== null;
1951
+ }
1952
+ function isVariableType(t) {
1953
+ return typeof t === "string" && t in DEFAULT_TYPEOF;
1954
+ }
1955
+ function isCompositionVariable(v) {
1956
+ if (!isRecord(v)) return false;
1957
+ if (typeof v.id !== "string" || typeof v.label !== "string") return false;
1958
+ if (!isVariableType(v.type)) return false;
1959
+ if (typeof v.default !== DEFAULT_TYPEOF[v.type]) return false;
1960
+ if (v.type === "enum" && !Array.isArray(v.options)) return false;
1961
+ return true;
1962
+ }
1963
+ function parseCompositionVariables(htmlEl) {
1964
+ const variablesAttr = htmlEl.getAttribute("data-composition-variables");
1965
+ if (!variablesAttr) {
1966
+ return [];
1967
+ }
1968
+ try {
1969
+ const parsed = JSON.parse(variablesAttr);
1970
+ if (!Array.isArray(parsed)) {
1971
+ return [];
1972
+ }
1973
+ return parsed.filter(isCompositionVariable);
1974
+ } catch {
1975
+ return [];
1976
+ }
1977
+ }
1978
+
1939
1979
  // src/hfIds.ts
1940
1980
  import { parseHTML } from "linkedom";
1941
1981
  var EXCLUDED_TAGS = /* @__PURE__ */ new Set([
@@ -1987,7 +2027,12 @@ function mintHfId(el, assigned) {
1987
2027
  return id;
1988
2028
  }
1989
2029
  function isCompositionTemplate(el) {
1990
- return el.tagName.toLowerCase() === "template" && el.getAttribute("data-composition-id") !== null;
2030
+ if (el.tagName.toLowerCase() !== "template") return false;
2031
+ if (el.getAttribute("data-composition-id") !== null) return true;
2032
+ for (const child of Array.from(el.children)) {
2033
+ if (child.getAttribute("data-composition-id") !== null) return true;
2034
+ }
2035
+ return false;
1991
2036
  }
1992
2037
  function walkElements(root, visit) {
1993
2038
  for (const child of Array.from(root.children)) {
@@ -2615,44 +2660,6 @@ function extractCompositionMetadata(html) {
2615
2660
  variables
2616
2661
  };
2617
2662
  }
2618
- function parseCompositionVariables(htmlEl) {
2619
- const variablesAttr = htmlEl.getAttribute("data-composition-variables");
2620
- if (!variablesAttr) {
2621
- return [];
2622
- }
2623
- try {
2624
- const parsed = JSON.parse(variablesAttr);
2625
- if (!Array.isArray(parsed)) {
2626
- return [];
2627
- }
2628
- return parsed.filter((v) => {
2629
- if (typeof v !== "object" || v === null) return false;
2630
- if (typeof v.id !== "string" || typeof v.label !== "string") return false;
2631
- if (!["string", "number", "color", "boolean", "enum", "font", "image"].includes(v.type))
2632
- return false;
2633
- switch (v.type) {
2634
- case "string":
2635
- return typeof v.default === "string";
2636
- case "number":
2637
- return typeof v.default === "number";
2638
- case "color":
2639
- return typeof v.default === "string";
2640
- case "boolean":
2641
- return typeof v.default === "boolean";
2642
- case "enum":
2643
- return typeof v.default === "string" && Array.isArray(v.options);
2644
- case "font":
2645
- return typeof v.default === "string";
2646
- case "image":
2647
- return typeof v.default === "string";
2648
- default:
2649
- return false;
2650
- }
2651
- });
2652
- } catch {
2653
- return [];
2654
- }
2655
- }
2656
2663
  function validateCompositionHtml(html) {
2657
2664
  const errors = [];
2658
2665
  const warnings = [];
@@ -2936,6 +2943,110 @@ function decodeUrlPathVariants(path) {
2936
2943
  return variants;
2937
2944
  }
2938
2945
 
2946
+ // src/variableUsage.ts
2947
+ import * as acorn3 from "acorn";
2948
+ import * as acornWalk3 from "acorn-walk";
2949
+ function isGetVariablesCallee(callee) {
2950
+ if (callee?.type === "Identifier") return callee.name === "getVariables";
2951
+ if (callee?.type === "MemberExpression" && !callee.computed) {
2952
+ return callee.property?.type === "Identifier" && callee.property.name === "getVariables";
2953
+ }
2954
+ return false;
2955
+ }
2956
+ function collectFromObjectPattern(pattern, out) {
2957
+ for (const prop of pattern.properties ?? []) {
2958
+ if (prop?.type === "RestElement") {
2959
+ out.incomplete();
2960
+ continue;
2961
+ }
2962
+ if (prop?.type !== "Property") continue;
2963
+ if (prop.computed === true) {
2964
+ out.incomplete();
2965
+ } else if (prop.key?.type === "Identifier") {
2966
+ out.use(String(prop.key.name));
2967
+ } else if (prop.key?.type === "Literal" && typeof prop.key.value === "string") {
2968
+ out.use(prop.key.value);
2969
+ } else {
2970
+ out.incomplete();
2971
+ }
2972
+ }
2973
+ }
2974
+ function collectFromMemberAccess(member, out) {
2975
+ if (member.computed !== true && member.property?.type === "Identifier") {
2976
+ out.use(String(member.property.name));
2977
+ } else if (member.computed === true && member.property?.type === "Literal" && typeof member.property.value === "string") {
2978
+ out.use(member.property.value);
2979
+ } else {
2980
+ out.incomplete();
2981
+ }
2982
+ }
2983
+ function classifyValueRead(parent, valueNode, out) {
2984
+ if (!parent || parent.type === "ExpressionStatement") {
2985
+ return null;
2986
+ }
2987
+ if (parent.type === "MemberExpression" && parent.object === valueNode) {
2988
+ collectFromMemberAccess(parent, out);
2989
+ return null;
2990
+ }
2991
+ if (parent.type === "VariableDeclarator" && parent.init === valueNode) {
2992
+ if (parent.id?.type === "ObjectPattern") {
2993
+ collectFromObjectPattern(parent.id, out);
2994
+ return null;
2995
+ }
2996
+ if (parent.id?.type === "Identifier") return String(parent.id.name);
2997
+ out.incomplete();
2998
+ return null;
2999
+ }
3000
+ out.incomplete();
3001
+ return null;
3002
+ }
3003
+ function scanVariableUsage(scriptText) {
3004
+ const usedIds = [];
3005
+ const seen = /* @__PURE__ */ new Set();
3006
+ let scanIncomplete = false;
3007
+ const sink = {
3008
+ use(id) {
3009
+ if (!seen.has(id)) {
3010
+ seen.add(id);
3011
+ usedIds.push(id);
3012
+ }
3013
+ },
3014
+ incomplete() {
3015
+ scanIncomplete = true;
3016
+ }
3017
+ };
3018
+ let ast;
3019
+ try {
3020
+ ast = acorn3.parse(scriptText, { ecmaVersion: "latest", sourceType: "script" });
3021
+ } catch {
3022
+ return { usedIds: [], scanIncomplete: true };
3023
+ }
3024
+ const aliases = /* @__PURE__ */ new Set();
3025
+ acornWalk3.ancestor(ast, {
3026
+ CallExpression(node, _, ancestors) {
3027
+ if (!isGetVariablesCallee(node.callee)) return;
3028
+ const parent = ancestors[ancestors.length - 2];
3029
+ const alias = classifyValueRead(parent, node, sink);
3030
+ if (alias) aliases.add(alias);
3031
+ }
3032
+ });
3033
+ if (aliases.size > 0) {
3034
+ acornWalk3.ancestor(ast, {
3035
+ // fallow-ignore-next-line complexity
3036
+ Identifier(node, _, ancestors) {
3037
+ if (!aliases.has(String(node.name))) return;
3038
+ const parent = ancestors[ancestors.length - 2];
3039
+ if (!parent) return;
3040
+ if (parent.type === "VariableDeclarator" && parent.id === node) return;
3041
+ if (parent.type === "MemberExpression" && parent.property === node) return;
3042
+ if (parent.type === "Property" && parent.key === node && parent.computed !== true) return;
3043
+ if (classifyValueRead(parent, node, sink)) sink.incomplete();
3044
+ }
3045
+ });
3046
+ }
3047
+ return { usedIds, scanIncomplete };
3048
+ }
3049
+
2939
3050
  // src/fontAliases.ts
2940
3051
  var FONT_ALIAS_MAP = {
2941
3052
  // ── Canonical bundled fonts (self-referencing) ────────────────────────
@@ -3077,11 +3188,13 @@ export {
3077
3188
  keyframesToGsapAnimations,
3078
3189
  mintHfId,
3079
3190
  normalizeResolutionFlag,
3191
+ parseCompositionVariables,
3080
3192
  parseGsapScriptAcorn as parseGsapScript,
3081
3193
  parseHtml,
3082
3194
  queryByAttr,
3083
3195
  removeElementFromHtml,
3084
3196
  resolveAliasDisplayName,
3197
+ scanVariableUsage,
3085
3198
  serializeGsapAnimations,
3086
3199
  unrollComputedTimeline,
3087
3200
  updateElementInHtml,