Skip to content

Commit

Permalink
3.12.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Igorkowalski94 committed Dec 8, 2024
1 parent 4bd9767 commit ef79b15
Show file tree
Hide file tree
Showing 17 changed files with 84 additions and 20 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"author": "Igor Kowalski (Igorkowalski94)",
"name": "eslint-plugin-project-structure",
"version": "3.11.0",
"version": "3.12.0",
"license": "MIT",
"description": "Powerful ESLint plugin with rules to help you achieve a scalable, consistent, and well-structured project. Create your own framework! Define your folder structure, file composition, advanced naming conventions, and create independent modules. Take your project to the next level and save time by automating the review of key principles of a healthy project! react folder structure react file structure react project structure react conventions architecture react next.js angular node solid vue svelte",
"keywords": [
Expand Down
21 changes: 17 additions & 4 deletions src/helpers/getProjectRoot.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,28 @@ describe("getProjectRoot", () => {
.spyOn(path, "dirname")
.mockReturnValue(path.resolve("c:/users/project/node_modules/test.ts"));

expect(getProjectRoot()).toEqual(path.resolve("c:/users/project"));
expect(getProjectRoot({ cwd: "cwd" })).toEqual(
path.resolve("c:/users/project"),
);
});

it("should return cwd when path does not contain node_modules", () => {
jest
.spyOn(path, "dirname")
.mockReturnValue(path.resolve("c:/users/project/test.ts"));

expect(getProjectRoot({ cwd: "cwd" })).toEqual("cwd");
});

it("should return rootPath with projectRootConfig", () => {
jest
.spyOn(path, "dirname")
.mockReturnValue(path.resolve("c:/users/project/node_modules/test.ts"));
expect(getProjectRoot("packages/package-name")).toEqual(
path.resolve("c:/users/project/packages/package-name"),
);
expect(
getProjectRoot({
cwd: "cwd",
projectRootConfig: "packages/package-name",
}),
).toEqual(path.resolve("c:/users/project/packages/package-name"));
});
});
13 changes: 12 additions & 1 deletion src/helpers/getProjectRoot.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import path, { dirname, sep } from "path";

export const getProjectRoot = (projectRootConfig?: string): string => {
interface GetProjectRootProps {
cwd: string;
projectRootConfig?: string;
}

export const getProjectRoot = ({
cwd,
projectRootConfig,
}: GetProjectRootProps): string => {
const dirnameSplit = dirname(__filename).split(sep);

const indexOfNodeModules = dirnameSplit.indexOf("node_modules");

if (indexOfNodeModules === -1) return cwd;

const rootPath = dirnameSplit.slice(0, indexOfNodeModules).join(sep);

if (!projectRootConfig) return rootPath;
Expand Down
8 changes: 5 additions & 3 deletions src/helpers/readConfigFile/helpers/getConfigPath.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@ describe("getConfigPath", () => {
it("should throw getMissingConfigFileError when config path is missing", () => {
(getProjectRoot as jest.Mock).mockReturnValue("src");

expect(() => getConfigPath({ key: "ruleKey", settings: {} })).toThrow(
getMissingConfigFileError("ruleKey"),
);
expect(() =>
getConfigPath({ key: "ruleKey", settings: {}, cwd: "cwd" }),
).toThrow(getMissingConfigFileError("ruleKey"));
});

it("should return config path when settings contain config path - relative", () => {
Expand All @@ -31,6 +31,7 @@ describe("getConfigPath", () => {
getConfigPath({
key: "ruleKey",
settings: { ruleKey: "config.json" },
cwd: "cwd",
}),
).toEqual("C:\\relative\\src\\config.json");
});
Expand All @@ -48,6 +49,7 @@ describe("getConfigPath", () => {
settings: {
ruleKey: "D:\\relative\\src\\config.json",
},
cwd: "cwd",
}),
).toEqual("D:\\relative\\src\\config.json");
});
Expand Down
4 changes: 3 additions & 1 deletion src/helpers/readConfigFile/helpers/getConfigPath.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,17 @@ import { getProjectRoot } from "helpers/getProjectRoot";
interface GetConfigPathProps {
settings: SharedConfigurationSettings;
key: string;
cwd: string;
}

export const getConfigPath = ({
settings,
key,
cwd,
}: GetConfigPathProps): string => {
const configPath = settings[key];

if (!configPath) throw getMissingConfigFileError(key);

return path.resolve(getProjectRoot(), configPath as string);
return path.resolve(getProjectRoot({ cwd }), configPath as string);
};
5 changes: 5 additions & 0 deletions src/helpers/readConfigFile/readConfigFile.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ describe("readConfigFile", () => {
key: "",
options: [{ name: "options" }],
settings: {},
cwd: "cwd",
}),
).toEqual([
{
Expand All @@ -51,6 +52,7 @@ describe("readConfigFile", () => {
key: "",
options: undefined,
settings: {},
cwd: "cwd",
}),
).toEqual({
name: "json",
Expand All @@ -66,6 +68,7 @@ describe("readConfigFile", () => {
key: "",
options: undefined,
settings: {},
cwd: "cwd",
}),
).toEqual({
name: "jsonc",
Expand All @@ -81,6 +84,7 @@ describe("readConfigFile", () => {
key: "",
options: undefined,
settings: {},
cwd: "cwd",
}),
).toEqual({
name: "yaml",
Expand All @@ -95,6 +99,7 @@ describe("readConfigFile", () => {
key: "",
options: undefined,
settings: {},
cwd: "cwd",
}),
).toThrow(getInvalidConfigFileError("config.error"));
});
Expand Down
3 changes: 3 additions & 0 deletions src/helpers/readConfigFile/readConfigFile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,21 @@ interface ReadConfigFileProps<T> {
key: string;
settings: SharedConfigurationSettings;
options: T | undefined;
cwd: string;
}

export const readConfigFile = <T>({
key,
settings,
options,
cwd,
}: ReadConfigFileProps<T>): T => {
if (options) return options;

const configPath = getConfigPath({
key,
settings,
cwd,
});

let config = undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,19 @@ export const getFileCompositionConfig = ({
filename,
settings,
options,
cwd,
}: Context): GetFileCompositionConfigReturn => {
const config = readConfigFile<FileCompositionConfig>({
key: "project-structure/file-composition-config-path",
settings,
options: options[0],
cwd,
});

validateConfig({ config, schema: FILE_COMPOSITION_SCHEMA });

const filenamePath = path.relative(
getProjectRoot(config.projectRoot),
getProjectRoot({ cwd, projectRootConfig: config.projectRoot }),
filename,
);
const fileConfig = config.filesRules.find(({ filePattern }) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const validateFile = ({
name,
expressionName,
context,
context: { filename },
context: { filename, cwd },
node,
nodeType,
fileConfig,
Expand All @@ -50,7 +50,7 @@ export const validateFile = ({
isCorrectScope({ expect: "nestedSelectors", scope }),
);
const filenamePath = path.relative(
getProjectRoot(config.projectRoot),
getProjectRoot({ cwd, projectRootConfig: config.projectRoot }),
filename,
);
const regexParameters = config.regexParameters;
Expand Down
8 changes: 6 additions & 2 deletions src/rules/folderStructure/helpers/handleProgram.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,20 @@ export interface HandleProgramProps {
}

export const handleProgram = ({
context: { settings, filename, options, report },
context: { settings, filename, options, report, cwd },
node,
}: HandleProgramProps): void => {
const config = readConfigFile<FolderStructureConfig>({
key: "project-structure/folder-structure-config-path",
settings,
options: options[0],
cwd,
});

const projectRoot = getProjectRoot(config.projectRoot);
const projectRoot = getProjectRoot({
cwd,
projectRootConfig: config.projectRoot,
});
const structureRoot = path.resolve(projectRoot, config.structureRoot ?? ".");

if (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,18 @@ import {
export const getIndependentModulesConfig = ({
options,
settings,
cwd,
}: Context): IndependentModulesConfig => {
const config = readConfigFile<IndependentModulesConfig>({
key: "project-structure/independent-modules-config-path",
settings,
options: options[0],
cwd,
});

validateConfig({ config, schema: INDEPENDENT_MODULES_SCHEMA });

const pathAliases = getPathAliases({ config });
const pathAliases = getPathAliases({ config, cwd });

return { ...config, pathAliases };
};
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ describe("getPathAliases", () => {
expect(
getPathAliases({
config: config as IndependentModulesConfig,
cwd: "cwd",
}),
).toEqual(expected);
});
Expand All @@ -107,6 +108,7 @@ describe("getPathAliases", () => {
expect(
getPathAliases({
config: { modules: [] },
cwd: "cwd",
}),
).toEqual(undefined);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ import {

interface GetPathAliasesProps {
config: IndependentModulesConfig;
cwd: string;
}

export const getPathAliases = ({
config,
cwd,
}: GetPathAliasesProps): PathAliases | undefined => {
const { pathAliases } = config;

if (pathAliases) return pathAliases;

const projectRoot = getProjectRoot();
const projectRoot = getProjectRoot({ cwd });

const tsconfigPath = config.tsconfigPath
? path.resolve(projectRoot, config.tsconfigPath)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@ describe("isExternalImport", () => {
).toEqual(false);
});

it("should return true when importPath startsWith https://", () => {
expect(
isExternalImport(
"https://esm.sh/react@18",
"C:\\Users\\user\\Desktop\\repo",
),
).toEqual(true);
});

it("should return true if import is external", () => {
jest
.spyOn(path, "join")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export const isExternalImport = (
projectRoot: string,
): boolean => {
if (importPath.startsWith(".")) return false;
if (importPath.startsWith("https://")) return true;

const importPathFirstElement = importPath.split(/[.:/]/)[0];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@ interface ValidateAllProps {
filename: string;
importPath: string;
config: IndependentModulesConfig;
cwd: string;
}

export const validateAll = ({
filename,
importPath,
config,
cwd,
}: ValidateAllProps): void => {
const { extensions, pathAliases } = config;

const projectRoot = getProjectRoot();
const projectRootWithBaseUrl = getProjectRoot(pathAliases?.baseUrl);
const projectRoot = getProjectRoot({ cwd });
const projectRootWithBaseUrl = getProjectRoot({
projectRootConfig: pathAliases?.baseUrl,
cwd,
});

const importPaths = getImportPaths({
importPath,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export interface ValidateImportProps {

export const validateImport = ({
importPath,
context: { filename, report },
context: { filename, report, cwd },
node,
config,
}: ValidateImportProps): void => {
Expand All @@ -31,6 +31,7 @@ export const validateImport = ({
filename,
importPath,
config,
cwd,
});
} catch (error) {
if (!finalErrorGuard(error)) throw error;
Expand Down

0 comments on commit ef79b15

Please sign in to comment.