@hyperframes/lint 0.8.193 → 0.8.194

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/browser.js CHANGED
@@ -814,6 +814,96 @@ function buildLintContext(html, options = {}) {
814
814
  // src/rules/core.ts
815
815
  import postcss from "postcss";
816
816
  import selectorParser from "postcss-selector-parser";
817
+
818
+ // src/shaderDomains.ts
819
+ import { parse as parse2, parseExpressionAt } from "acorn";
820
+ import { simple as simple2 } from "acorn-walk";
821
+ var GLSL_SCRIPT_TYPES = /* @__PURE__ */ new Set(["x-shader/x-fragment", "x-shader/x-vertex", "text/glsl"]);
822
+ function withoutComments(source) {
823
+ return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
824
+ }
825
+ function staticShaders(source) {
826
+ const shaders = [];
827
+ try {
828
+ const ast = parse2(source, {
829
+ ecmaVersion: "latest",
830
+ sourceType: "module",
831
+ allowReturnOutsideFunction: true
832
+ });
833
+ simple2(ast, {
834
+ Literal(node) {
835
+ if (typeof node.value !== "string") return;
836
+ shaders.push({
837
+ text: node.value,
838
+ start: node.start + 1,
839
+ exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
840
+ });
841
+ },
842
+ TemplateLiteral(node) {
843
+ if (node.expressions.length !== 0) return;
844
+ const value = node.quasis[0]?.value;
845
+ if (value?.cooked == null) return;
846
+ shaders.push({
847
+ text: value.cooked,
848
+ start: node.start + 1,
849
+ exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
850
+ });
851
+ }
852
+ });
853
+ } catch {
854
+ }
855
+ return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
856
+ }
857
+ function isNumber(node, value) {
858
+ return node?.type === "Literal" && node.value === value;
859
+ }
860
+ function isCall(node, name) {
861
+ return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
862
+ }
863
+ function unboundedCosine(node) {
864
+ if (node.type !== "CallExpression") return false;
865
+ if (isCall(node, "dot")) return node.arguments.length === 2;
866
+ if (!isCall(node, "max") || node.arguments.length !== 2) return false;
867
+ const a = argumentAt(node, 0);
868
+ const b = argumentAt(node, 1);
869
+ return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
870
+ }
871
+ function argumentAt(call, index) {
872
+ const node = call.arguments[index];
873
+ return node?.type === "SpreadElement" ? void 0 : node;
874
+ }
875
+ function zeroFlooredDot(a, b) {
876
+ return isCall(a, "dot") && isNumber(b, 0);
877
+ }
878
+ function unsafeCosinePower(call) {
879
+ if (call.arguments.length !== 2) return false;
880
+ const [base2] = call.arguments;
881
+ return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
882
+ }
883
+ function unsafePowOffsets(source) {
884
+ const offsets = [];
885
+ const masked = withoutComments(source);
886
+ for (const match of masked.matchAll(/\bpow\s*\(/g)) {
887
+ try {
888
+ const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
889
+ simple2(expression, {
890
+ CallExpression(node) {
891
+ if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
892
+ }
893
+ });
894
+ } catch {
895
+ }
896
+ }
897
+ return offsets;
898
+ }
899
+ function shaderDomainOffsets(source, glsl = false) {
900
+ const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
901
+ return shaders.flatMap(
902
+ ({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
903
+ );
904
+ }
905
+
906
+ // src/rules/core.ts
817
907
  import {
818
908
  HTML_BODY_CSS_WIDTH_FIRST_RE,
819
909
  HTML_BODY_CSS_HEIGHT_FIRST_RE,
@@ -823,7 +913,8 @@ var SCRIPT_SYNTAX_EXEMPT_TYPES = /* @__PURE__ */ new Set([
823
913
  "application/json",
824
914
  "application/hyperframes-slideshow+json",
825
915
  "importmap",
826
- "module"
916
+ "module",
917
+ ...GLSL_SCRIPT_TYPES
827
918
  ]);
828
919
  function repeatedDescendantId(selector) {
829
920
  let repeated = null;
@@ -2579,20 +2670,20 @@ function findAudioGroupCarveAttrFindings(ctx) {
2579
2670
  }
2580
2671
 
2581
2672
  // src/scriptPositions.ts
2582
- import { parse as parse2 } from "acorn";
2583
- import { simple as simple2 } from "acorn-walk";
2673
+ import { parse as parse3 } from "acorn";
2674
+ import { simple as simple3 } from "acorn-walk";
2584
2675
  var callIndexes = /* @__PURE__ */ new WeakMap();
2585
2676
  function callsFor(script) {
2586
2677
  const cached = callIndexes.get(script);
2587
2678
  if (cached) return cached;
2588
2679
  const calls = [];
2589
2680
  try {
2590
- const ast = parse2(script.content, {
2681
+ const ast = parse3(script.content, {
2591
2682
  ecmaVersion: "latest",
2592
2683
  sourceType: "script",
2593
2684
  allowReturnOutsideFunction: true
2594
2685
  });
2595
- simple2(ast, {
2686
+ simple3(ast, {
2596
2687
  CallExpression: (node) => {
2597
2688
  calls.push(node);
2598
2689
  }
@@ -6500,93 +6591,6 @@ var structureRules = [
6500
6591
  }
6501
6592
  ];
6502
6593
 
6503
- // src/shaderDomains.ts
6504
- import { parse as parse3, parseExpressionAt } from "acorn";
6505
- import { simple as simple3 } from "acorn-walk";
6506
- function withoutComments(source) {
6507
- return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
6508
- }
6509
- function staticShaders(source) {
6510
- const shaders = [];
6511
- try {
6512
- const ast = parse3(source, {
6513
- ecmaVersion: "latest",
6514
- sourceType: "module",
6515
- allowReturnOutsideFunction: true
6516
- });
6517
- simple3(ast, {
6518
- Literal(node) {
6519
- if (typeof node.value !== "string") return;
6520
- shaders.push({
6521
- text: node.value,
6522
- start: node.start + 1,
6523
- exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
6524
- });
6525
- },
6526
- TemplateLiteral(node) {
6527
- if (node.expressions.length !== 0) return;
6528
- const value = node.quasis[0]?.value;
6529
- if (value?.cooked == null) return;
6530
- shaders.push({
6531
- text: value.cooked,
6532
- start: node.start + 1,
6533
- exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
6534
- });
6535
- }
6536
- });
6537
- } catch {
6538
- }
6539
- return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
6540
- }
6541
- function isNumber(node, value) {
6542
- return node?.type === "Literal" && node.value === value;
6543
- }
6544
- function isCall(node, name) {
6545
- return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
6546
- }
6547
- function unboundedCosine(node) {
6548
- if (node.type !== "CallExpression") return false;
6549
- if (isCall(node, "dot")) return node.arguments.length === 2;
6550
- if (!isCall(node, "max") || node.arguments.length !== 2) return false;
6551
- const a = argumentAt(node, 0);
6552
- const b = argumentAt(node, 1);
6553
- return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
6554
- }
6555
- function argumentAt(call, index) {
6556
- const node = call.arguments[index];
6557
- return node?.type === "SpreadElement" ? void 0 : node;
6558
- }
6559
- function zeroFlooredDot(a, b) {
6560
- return isCall(a, "dot") && isNumber(b, 0);
6561
- }
6562
- function unsafeCosinePower(call) {
6563
- if (call.arguments.length !== 2) return false;
6564
- const [base2] = call.arguments;
6565
- return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
6566
- }
6567
- function unsafePowOffsets(source) {
6568
- const offsets = [];
6569
- const masked = withoutComments(source);
6570
- for (const match of masked.matchAll(/\bpow\s*\(/g)) {
6571
- try {
6572
- const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
6573
- simple3(expression, {
6574
- CallExpression(node) {
6575
- if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
6576
- }
6577
- });
6578
- } catch {
6579
- }
6580
- }
6581
- return offsets;
6582
- }
6583
- function shaderDomainOffsets(source, glsl = false) {
6584
- const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
6585
- return shaders.flatMap(
6586
- ({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
6587
- );
6588
- }
6589
-
6590
6594
  // src/rules/shaders.ts
6591
6595
  function shaderDomainWarning() {
6592
6596
  return {
@@ -6601,7 +6605,7 @@ var shaderRules = [
6601
6605
  const tag = `<script ${script.attrs}>`;
6602
6606
  if (readAttr(tag, "src") !== null) return [];
6603
6607
  const type = readAttr(tag, "type") ?? "";
6604
- const glsl = /^(?:x-shader\/x-(?:fragment|vertex)|text\/glsl)$/i.test(type);
6608
+ const glsl = GLSL_SCRIPT_TYPES.has(type.toLowerCase());
6605
6609
  if (type && !glsl && !/^(?:module|(?:text|application)\/javascript)$/i.test(type)) return [];
6606
6610
  return shaderDomainOffsets(script.content, glsl).map((offset) => ({
6607
6611
  ...shaderDomainWarning(),
package/dist/index.js CHANGED
@@ -820,6 +820,96 @@ function buildLintContext(html, options = {}) {
820
820
  // src/rules/core.ts
821
821
  import postcss from "postcss";
822
822
  import selectorParser from "postcss-selector-parser";
823
+
824
+ // src/shaderDomains.ts
825
+ import { parse as parse2, parseExpressionAt } from "acorn";
826
+ import { simple as simple2 } from "acorn-walk";
827
+ var GLSL_SCRIPT_TYPES = /* @__PURE__ */ new Set(["x-shader/x-fragment", "x-shader/x-vertex", "text/glsl"]);
828
+ function withoutComments(source) {
829
+ return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
830
+ }
831
+ function staticShaders(source) {
832
+ const shaders = [];
833
+ try {
834
+ const ast = parse2(source, {
835
+ ecmaVersion: "latest",
836
+ sourceType: "module",
837
+ allowReturnOutsideFunction: true
838
+ });
839
+ simple2(ast, {
840
+ Literal(node) {
841
+ if (typeof node.value !== "string") return;
842
+ shaders.push({
843
+ text: node.value,
844
+ start: node.start + 1,
845
+ exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
846
+ });
847
+ },
848
+ TemplateLiteral(node) {
849
+ if (node.expressions.length !== 0) return;
850
+ const value = node.quasis[0]?.value;
851
+ if (value?.cooked == null) return;
852
+ shaders.push({
853
+ text: value.cooked,
854
+ start: node.start + 1,
855
+ exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
856
+ });
857
+ }
858
+ });
859
+ } catch {
860
+ }
861
+ return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
862
+ }
863
+ function isNumber(node, value) {
864
+ return node?.type === "Literal" && node.value === value;
865
+ }
866
+ function isCall(node, name) {
867
+ return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
868
+ }
869
+ function unboundedCosine(node) {
870
+ if (node.type !== "CallExpression") return false;
871
+ if (isCall(node, "dot")) return node.arguments.length === 2;
872
+ if (!isCall(node, "max") || node.arguments.length !== 2) return false;
873
+ const a = argumentAt(node, 0);
874
+ const b = argumentAt(node, 1);
875
+ return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
876
+ }
877
+ function argumentAt(call, index) {
878
+ const node = call.arguments[index];
879
+ return node?.type === "SpreadElement" ? void 0 : node;
880
+ }
881
+ function zeroFlooredDot(a, b) {
882
+ return isCall(a, "dot") && isNumber(b, 0);
883
+ }
884
+ function unsafeCosinePower(call) {
885
+ if (call.arguments.length !== 2) return false;
886
+ const [base2] = call.arguments;
887
+ return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
888
+ }
889
+ function unsafePowOffsets(source) {
890
+ const offsets = [];
891
+ const masked = withoutComments(source);
892
+ for (const match of masked.matchAll(/\bpow\s*\(/g)) {
893
+ try {
894
+ const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
895
+ simple2(expression, {
896
+ CallExpression(node) {
897
+ if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
898
+ }
899
+ });
900
+ } catch {
901
+ }
902
+ }
903
+ return offsets;
904
+ }
905
+ function shaderDomainOffsets(source, glsl = false) {
906
+ const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
907
+ return shaders.flatMap(
908
+ ({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
909
+ );
910
+ }
911
+
912
+ // src/rules/core.ts
823
913
  import {
824
914
  HTML_BODY_CSS_WIDTH_FIRST_RE,
825
915
  HTML_BODY_CSS_HEIGHT_FIRST_RE,
@@ -829,7 +919,8 @@ var SCRIPT_SYNTAX_EXEMPT_TYPES = /* @__PURE__ */ new Set([
829
919
  "application/json",
830
920
  "application/hyperframes-slideshow+json",
831
921
  "importmap",
832
- "module"
922
+ "module",
923
+ ...GLSL_SCRIPT_TYPES
833
924
  ]);
834
925
  function repeatedDescendantId(selector) {
835
926
  let repeated = null;
@@ -2585,20 +2676,20 @@ function findAudioGroupCarveAttrFindings(ctx) {
2585
2676
  }
2586
2677
 
2587
2678
  // src/scriptPositions.ts
2588
- import { parse as parse2 } from "acorn";
2589
- import { simple as simple2 } from "acorn-walk";
2679
+ import { parse as parse3 } from "acorn";
2680
+ import { simple as simple3 } from "acorn-walk";
2590
2681
  var callIndexes = /* @__PURE__ */ new WeakMap();
2591
2682
  function callsFor(script) {
2592
2683
  const cached = callIndexes.get(script);
2593
2684
  if (cached) return cached;
2594
2685
  const calls = [];
2595
2686
  try {
2596
- const ast = parse2(script.content, {
2687
+ const ast = parse3(script.content, {
2597
2688
  ecmaVersion: "latest",
2598
2689
  sourceType: "script",
2599
2690
  allowReturnOutsideFunction: true
2600
2691
  });
2601
- simple2(ast, {
2692
+ simple3(ast, {
2602
2693
  CallExpression: (node) => {
2603
2694
  calls.push(node);
2604
2695
  }
@@ -6506,93 +6597,6 @@ var structureRules = [
6506
6597
  }
6507
6598
  ];
6508
6599
 
6509
- // src/shaderDomains.ts
6510
- import { parse as parse3, parseExpressionAt } from "acorn";
6511
- import { simple as simple3 } from "acorn-walk";
6512
- function withoutComments(source) {
6513
- return source.replace(/\/\*[\s\S]*?\*\/|\/\/[^\r\n]*/g, (text) => text.replace(/[^\r\n]/g, " "));
6514
- }
6515
- function staticShaders(source) {
6516
- const shaders = [];
6517
- try {
6518
- const ast = parse3(source, {
6519
- ecmaVersion: "latest",
6520
- sourceType: "module",
6521
- allowReturnOutsideFunction: true
6522
- });
6523
- simple3(ast, {
6524
- Literal(node) {
6525
- if (typeof node.value !== "string") return;
6526
- shaders.push({
6527
- text: node.value,
6528
- start: node.start + 1,
6529
- exactOffsets: source.slice(node.start + 1, node.end - 1) === node.value
6530
- });
6531
- },
6532
- TemplateLiteral(node) {
6533
- if (node.expressions.length !== 0) return;
6534
- const value = node.quasis[0]?.value;
6535
- if (value?.cooked == null) return;
6536
- shaders.push({
6537
- text: value.cooked,
6538
- start: node.start + 1,
6539
- exactOffsets: source.slice(node.start + 1, node.end - 1) === value.cooked
6540
- });
6541
- }
6542
- });
6543
- } catch {
6544
- }
6545
- return shaders.filter(({ text }) => /\bvoid\s+main\s*\(/.test(withoutComments(text)));
6546
- }
6547
- function isNumber(node, value) {
6548
- return node?.type === "Literal" && node.value === value;
6549
- }
6550
- function isCall(node, name) {
6551
- return node?.type === "CallExpression" && node.callee.type === "Identifier" && node.callee.name === name;
6552
- }
6553
- function unboundedCosine(node) {
6554
- if (node.type !== "CallExpression") return false;
6555
- if (isCall(node, "dot")) return node.arguments.length === 2;
6556
- if (!isCall(node, "max") || node.arguments.length !== 2) return false;
6557
- const a = argumentAt(node, 0);
6558
- const b = argumentAt(node, 1);
6559
- return zeroFlooredDot(a, b) || zeroFlooredDot(b, a);
6560
- }
6561
- function argumentAt(call, index) {
6562
- const node = call.arguments[index];
6563
- return node?.type === "SpreadElement" ? void 0 : node;
6564
- }
6565
- function zeroFlooredDot(a, b) {
6566
- return isCall(a, "dot") && isNumber(b, 0);
6567
- }
6568
- function unsafeCosinePower(call) {
6569
- if (call.arguments.length !== 2) return false;
6570
- const [base2] = call.arguments;
6571
- return base2?.type === "BinaryExpression" && base2.operator === "-" && base2.left.type !== "PrivateIdentifier" && isNumber(base2.left, 1) && unboundedCosine(base2.right);
6572
- }
6573
- function unsafePowOffsets(source) {
6574
- const offsets = [];
6575
- const masked = withoutComments(source);
6576
- for (const match of masked.matchAll(/\bpow\s*\(/g)) {
6577
- try {
6578
- const expression = parseExpressionAt(masked, match.index, { ecmaVersion: "latest" });
6579
- simple3(expression, {
6580
- CallExpression(node) {
6581
- if (node.start === match.index && unsafeCosinePower(node)) offsets.push(node.start);
6582
- }
6583
- });
6584
- } catch {
6585
- }
6586
- }
6587
- return offsets;
6588
- }
6589
- function shaderDomainOffsets(source, glsl = false) {
6590
- const shaders = glsl ? [{ text: source, start: 0, exactOffsets: true }] : staticShaders(source);
6591
- return shaders.flatMap(
6592
- ({ text, start, exactOffsets }) => unsafePowOffsets(text).map((offset) => exactOffsets ? start + offset : void 0)
6593
- );
6594
- }
6595
-
6596
6600
  // src/rules/shaders.ts
6597
6601
  function shaderDomainWarning() {
6598
6602
  return {
@@ -6607,7 +6611,7 @@ var shaderRules = [
6607
6611
  const tag = `<script ${script.attrs}>`;
6608
6612
  if (readAttr(tag, "src") !== null) return [];
6609
6613
  const type = readAttr(tag, "type") ?? "";
6610
- const glsl = /^(?:x-shader\/x-(?:fragment|vertex)|text\/glsl)$/i.test(type);
6614
+ const glsl = GLSL_SCRIPT_TYPES.has(type.toLowerCase());
6611
6615
  if (type && !glsl && !/^(?:module|(?:text|application)\/javascript)$/i.test(type)) return [];
6612
6616
  return shaderDomainOffsets(script.content, glsl).map((offset) => ({
6613
6617
  ...shaderDomainWarning(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperframes/lint",
3
- "version": "0.8.193",
3
+ "version": "0.8.194",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/heygen-com/hyperframes",
@@ -35,7 +35,7 @@
35
35
  "linkedom": "^0.18.12",
36
36
  "postcss": "^8.5.8",
37
37
  "postcss-selector-parser": "^7.1.4",
38
- "@hyperframes/parsers": "0.8.193"
38
+ "@hyperframes/parsers": "0.8.194"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/node": "^25.0.10",