diff --git a/.agents/memory/lit-analyzer-ts6.md b/.agents/memory/lit-analyzer-ts6.md index ebbb795..abfae86 100644 --- a/.agents/memory/lit-analyzer-ts6.md +++ b/.agents/memory/lit-analyzer-ts6.md @@ -31,7 +31,7 @@ registerHooks({ - Node runs the `.ts` script directly (type stripping), so no build step. - Import the package entry, or spawn the package's bin with `node:child_process`, rather than `await import("lit-analyzer/cli.js")`. - `project/no-asset-imports` allows `.js` subpaths, but the CLI file runs on + `project/no-asset-imports` allows `.js` (and `.mts`/`.mjs`) subpaths, but the CLI file runs on import and bypasses the package's public entry. - CI runs `npm run lit-check` as its own step. - It is tooling under `scripts/`: no tests; a narrow `overrides` entry for it diff --git a/.agents/memory/ts-only-files-and-imports.md b/.agents/memory/ts-only-files-and-imports.md index 8ac48f8..f488cd1 100644 --- a/.agents/memory/ts-only-files-and-imports.md +++ b/.agents/memory/ts-only-files-and-imports.md @@ -1,5 +1,5 @@ --- -description: Every file is .ts (no js/mjs/cjs/jsx/tsx, configs included); imports name only .ts files or .js package subpaths; CSS comes from HTML, JSON/SVG become .ts modules +description: Every file is .ts (no js/mjs/cjs/jsx/tsx, configs included); imports name only .ts files or .js/.mts/.mjs package subpaths; CSS comes from HTML, JSON/SVG become .ts modules --- The user's rule, from the Deno days and restated for Node (2026-10-12): "No @@ -12,19 +12,22 @@ plain `.ts`. Build output in a gitignored folder is the only JS. `noUncheckedIndexedAccess`). If a tool or framework seems to need a JS or TSX file, stop and flag it instead of adding one. -## No asset imports (2026-10-14, widened 2026-10-16) +## No asset imports (2026-10-14, widened 2026-10-16 and 2026-10-17) -`.ts` and `.js` imports are allowed: our own files stay `.ts`, and `.js` -covers package subpaths such as `lit/decorators.js`. -`project/no-asset-imports` (in `scripts/project-lint.ts`) fails: +`project/no-asset-imports` (in `scripts/project-lint.ts`; it was +`no-non-ts-imports` before 2026-10-16) fails: - a relative, absolute, `#`, or package-subpath specifier whose last segment - has any other extension: `.css`, `.json`, `.svg`, `.mjs`, `.tsx`; + has an extension other than `.ts`, `.js`, `.mts`, or `.mjs`: `.css`, + `.json`, `.svg`, `.jsx`, `.tsx`, and every other asset; - any `?query` suffix (`?raw`, `?url`, `?inline`); - any import attributes (`with { type: "json" }`, `with { type: "text" }`). -Bare packages (`lit`, `@types/json-schema`, `lodash.debounce`), `#` aliases, -and `node:` builtins pass. `@fortawesome/x/svgs/a.svg` fails. +`.js`, `.mts`, and `.mjs` are allowed (user decision, 2026-10-17) for package +subpaths such as `lit/decorators.js` or `pdfjs-dist/legacy/build/pdf.mjs`; +our own files are still `.ts` only. `.jsx` and `.tsx` stay banned. Bare +packages (`lit`, `@types/json-schema`, `lodash.debounce`), `#` aliases, and +`node:` builtins pass. `@fortawesome/x/svgs/a.svg` fails. ```ts import "./theme.css"; // no diff --git a/scripts/project-lint.ts b/scripts/project-lint.ts index 663997e..13da199 100644 --- a/scripts/project-lint.ts +++ b/scripts/project-lint.ts @@ -70,14 +70,18 @@ const noDisableCommentsRule: ProjectRule = { /** A module specifier read as a path: relative, absolute, or a `#` alias. */ const PATH_SPECIFIER_PATTERN: RegExp = /^[./#]/u; -/** Script module extensions an import may name: our `.ts` files and `.js` package subpaths. */ -const SCRIPT_EXTENSIONS: readonly string[] = [".ts", ".js"]; +/** + * Script module extensions an import may name: our `.ts` files and `.js`, + * `.mts`, or `.mjs` package subpaths. `.cts`, `.cjs`, `.tsx`, and `.jsx` are + * not among them. + */ +const SCRIPT_EXTENSIONS: ReadonlySet = new Set([".ts", ".js", ".mts", ".mjs"]); /** * Whether `source` names an asset rather than a script module: a query string - * such as `?raw`, or a final path segment with an extension other than `.ts` - * or `.js`. Bare package names are left alone, dots and all, as are - * extensionless paths. + * such as `?raw`, or a final path segment whose extension, from its last dot, + * is not `.ts`, `.js`, `.mts`, or `.mjs`. Bare package names are left alone, + * dots and all, as are extensionless paths. */ function isAssetSource(source: string): boolean { if (source.includes("?")) { @@ -94,25 +98,28 @@ function isAssetSource(source: string): boolean { if (lastSegment === "." || lastSegment === ".." || !lastSegment.includes(".")) { return false; } - return !SCRIPT_EXTENSIONS.some((extension: string): boolean => lastSegment.endsWith(extension)); + const extension: string = lastSegment.slice(lastSegment.lastIndexOf(".")); + return !SCRIPT_EXTENSIONS.has(extension); } /** * `no-asset-imports` — rejects importing anything but a script module: a * source path, static or a dynamic `import()` with a string literal, ending in - * an extension other than `.ts` or `.js` (`.css`, `.json`, `.svg`, `.tsx`) or - * carrying a query string (`?raw`, `?url`), and any import or export with - * import attributes. `.js` covers package subpaths such as - * `lit/decorators.js`. Bare package names, `#` aliases, and `node:` builtins + * an extension other than `.ts`, `.js`, `.mts`, or `.mjs` (`.css`, `.json`, + * `.svg`, `.jsx`, `.tsx`, `.cjs`) or carrying a query string (`?raw`, `?url`), + * and any import or export with import attributes. `.js`, `.mts`, and `.mjs` + * cover package subpaths such as `lit/decorators.js` or + * `pdfjs-dist/legacy/build/pdf.mjs`; our own files are still `.ts` only. Bare + * package names, `#` aliases, and `node:` builtins * without an extension pass; package subpaths are checked like paths. */ const noAssetImportsRule: ProjectRule = { meta: { type: "problem", - docs: { description: "Disallow importing assets instead of .ts or .js modules" }, + docs: { description: "Disallow importing assets instead of .ts, .js, .mts, or .mjs modules" }, schema: [], messages: { - extension: "Only .ts and .js modules may be imported.", + extension: "Only .ts, .js, .mts and .mjs modules may be imported.", attributes: "Import attributes are not allowed.", }, },