diff --git a/packages/lint/src/rules/adapters.test.ts b/packages/lint/src/rules/adapters.test.ts index d28e49abc..8e4f3ab51 100644 --- a/packages/lint/src/rules/adapters.test.ts +++ b/packages/lint/src/rules/adapters.test.ts @@ -124,6 +124,88 @@ describe("adapter rules", () => { expect(finding).toBeUndefined(); }); + it("does not report missing_three_script for an ESM +esm CDN import (jsdelivr)", async () => { + const html = ` + +
+ +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "missing_three_script"); + expect(finding).toBeUndefined(); + }); + + it("does not report missing_three_script for an esm.sh/three import", async () => { + const html = ` + +
+ +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "missing_three_script"); + expect(finding).toBeUndefined(); + }); + + it("does not report missing_three_script for a local three.module.js import", async () => { + const html = ` + +
+ +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "missing_three_script"); + expect(finding).toBeUndefined(); + }); + + it("does not report missing_three_script for a bare 'three' import (regression)", async () => { + const html = ` + +
+ +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "missing_three_script"); + expect(finding).toBeUndefined(); + }); + + it("still reports missing_three_script when THREE is used with no three loaded", async () => { + const html = ` + +
+ +`; + const result = await lintHyperframeHtml(html); + const finding = result.findings.find((f) => f.code === "missing_three_script"); + expect(finding).toBeDefined(); + expect(finding?.severity).toBe("error"); + }); + it("does not report any adapter errors for composition with no adapter usage", async () => { const html = ` diff --git a/packages/lint/src/rules/adapters.ts b/packages/lint/src/rules/adapters.ts index 2a9b05bc2..4de4b330b 100644 --- a/packages/lint/src/rules/adapters.ts +++ b/packages/lint/src/rules/adapters.ts @@ -36,8 +36,11 @@ export const adapterRules: Array<(ctx: LintContext) => HyperframeLintFinding[]> /["']three["']/.test(t) && /importmap/.test(scripts.find((s) => s.content === t)?.attrs || ""), ); - const hasThreeModuleImport = texts.some( - (t) => /\bimport\b.*['"]three['"]/.test(t) || /\bfrom\s+['"]three['"]/.test(t), + // Matches any import/from whose specifier contains "three" (bare 'three', or a + // URL/path like .../+esm, esm.sh/three, three.module.js), mirroring the loose + // /three/i treatment of