diff --git a/src/loaders/less/import-plugin.ts b/src/loaders/less/import-plugin.ts index 54b90659..a4d24612 100644 --- a/src/loaders/less/import-plugin.ts +++ b/src/loaders/less/import-plugin.ts @@ -1,13 +1,11 @@ import fs from "fs-extra"; -import { LoadedFile, Plugin, Less } from "less"; +import { LoadedFile, Plugin, FileManagerInterface, Less } from "less"; import resolveAsync from "../../utils/resolve-async"; import { moduleRe, getUrlOfPartial } from "../../utils/resolve-utils"; -// eslint-disable-next-line @typescript-eslint/explicit-function-return-type -const getManager = () => { +const getStylesFileManager = (): FileManagerInterface => { const less = require("less") as Less; - - class StylesFileManager extends less.FileManager { + return new (class extends less.AbstractFileManager implements FileManagerInterface { supports(): boolean { return true; } @@ -16,50 +14,47 @@ const getManager = () => { return false; } - async loadFile(filename: string, currentDirectory: string): Promise { - const options = { basedir: currentDirectory, extensions: [".less", ".css"] }; + async loadFile(filename: string, basedir: string): Promise { + const options = { basedir, extensions: [".less", ".css"] }; + let id: string; if (!moduleRe.test(filename)) { - let resolved: string; try { // Give precedence to importing a partial try { - resolved = await resolveAsync(getUrlOfPartial(filename), options); + id = await resolveAsync(getUrlOfPartial(filename), options); } catch (error) { - resolved = await resolveAsync(filename, options); + id = await resolveAsync(filename, options); } } catch (error) { // Give precedence to importing a partial try { - resolved = await resolveAsync(`./${getUrlOfPartial(filename)}`, options); + id = await resolveAsync(`./${getUrlOfPartial(filename)}`, options); } catch (error) { - resolved = await resolveAsync(`./${filename}`, options); + id = await resolveAsync(`./${filename}`, options); } } - return { filename: resolved, contents: await fs.readFile(resolved, "utf8") }; + return { filename: id, contents: await fs.readFile(id, "utf8") }; } const moduleUrl = filename.slice(1); const partialUrl = getUrlOfPartial(moduleUrl); // Give precedence to importing a partial - let resolved: string; try { - resolved = await resolveAsync(partialUrl, options); + id = await resolveAsync(partialUrl, options); } catch (error) { - resolved = await resolveAsync(moduleUrl, options); + id = await resolveAsync(moduleUrl, options); } - return { filename: resolved, contents: await fs.readFile(resolved, "utf8") }; + return { filename: id, contents: await fs.readFile(id, "utf8") }; } - } - - return new StylesFileManager(); + })(); }; const importPlugin: Plugin = { install(_, pluginManager) { - pluginManager.addFileManager(getManager()); + pluginManager.addFileManager(getStylesFileManager()); }, }; diff --git a/src/typings/less.d.ts b/src/typings/less.d.ts index aeda9b42..7c8e8814 100644 --- a/src/typings/less.d.ts +++ b/src/typings/less.d.ts @@ -4,7 +4,7 @@ declare module "less" { filename: string; relativeUrls: boolean; rootpath: string; - currentDirectory: string; + currentDir: string; entryPath: string; rootFilename: string; reference: boolean; @@ -34,18 +34,30 @@ declare module "less" { export type LoadOptions = { [k: string]: unknown }; - class AbstractFileManager {} - class FileManager extends AbstractFileManager { - supports(filename: string, currentDirectory: string, options: LoadOptions): boolean; - supportsSync(filename: string, currentDirectory: string, options: LoadOptions): boolean; - loadFile(filename: string, currentDirectory: string, options: LoadOptions): Promise; - loadFileSync(filename: string, currentDirectory: string, options: LoadOptions): LoadedFileSync; + export interface AbstractFileManagerInterface { + supportsSync(filename: string, currentDir: string, options: LoadOptions): boolean; + } + + export interface FileManagerInterface extends AbstractFileManagerInterface { + supports(filename: string, currentDir: string, options: LoadOptions): boolean; + loadFile(filename: string, currentDir: string, options: LoadOptions): Promise; + loadFileSync?(filename: string, currentDir: string, options: LoadOptions): LoadedFileSync; + } + + class AbstractFileManager implements AbstractFileManagerInterface { + supportsSync(filename: string, currentDir: string, options: LoadOptions): boolean; + } + + class FileManager extends AbstractFileManager implements FileManagerInterface { + supports(filename: string, currentDir: string, options: LoadOptions): boolean; + loadFile(filename: string, currentDir: string, options: LoadOptions): Promise; + loadFileSync?(filename: string, currentDir: string, options: LoadOptions): LoadedFileSync; } class PluginManager { constructor(less: Less); addPreProcessor(preProcessor: PreProcessor, priority?: number): void; - addFileManager(fileManager: FileManager): void; + addFileManager(fileManager: FileManagerInterface): void; } export interface Plugin { @@ -113,6 +125,7 @@ declare module "less" { sheets: HTMLLinkElement[]; version: number[]; + AbstractFileManager: typeof AbstractFileManager; FileManager: typeof FileManager; render(input: string, callback: RenderCallback): void;