refactor: add context keywords and improve hardcoded value suggestions

This commit is contained in:
imfozilbek
2025-11-27 19:27:07 +05:00
parent e8626dd03c
commit 07e6535633
3 changed files with 270 additions and 83 deletions

View File

@@ -80,3 +80,12 @@ export const ANEMIC_MODEL_MESSAGES = {
ENCAPSULATE_BUSINESS_RULES: "3. Encapsulate business rules inside entity methods", ENCAPSULATE_BUSINESS_RULES: "3. Encapsulate business rules inside entity methods",
USE_DOMAIN_EVENTS: "4. Use domain events to communicate state changes", USE_DOMAIN_EVENTS: "4. Use domain events to communicate state changes",
} }
/**
* Example values used in violation messages
*/
export const VIOLATION_EXAMPLE_VALUES = {
UNKNOWN: "unknown",
USER_REPOSITORY: "UserRepository",
FIND_ONE: "findOne",
}

View File

@@ -24,6 +24,106 @@ export const SUGGESTION_KEYWORDS = {
CONSOLE_ERROR: "console.error", CONSOLE_ERROR: "console.error",
} as const } as const
/**
* Context keywords for email detection
*/
export const EMAIL_CONTEXT_KEYWORDS = {
ADMIN: "admin",
SUPPORT: "support",
NOREPLY: "noreply",
NO_REPLY: "no-reply",
} as const
/**
* Context keywords for API key detection
*/
export const API_KEY_CONTEXT_KEYWORDS = {
SECRET: "secret",
PUBLIC: "public",
} as const
/**
* Context keywords for URL detection
*/
export const URL_CONTEXT_KEYWORDS = {
API: "api",
DATABASE: "database",
DB: "db",
MONGO: "mongo",
POSTGRES: "postgres",
PG: "pg",
} as const
/**
* Context keywords for IP address detection
*/
export const IP_CONTEXT_KEYWORDS = {
SERVER: "server",
REDIS: "redis",
} as const
/**
* Context keywords for file path detection
*/
export const FILE_PATH_CONTEXT_KEYWORDS = {
LOG: "log",
DATA: "data",
TEMP: "temp",
} as const
/**
* Context keywords for date detection
*/
export const DATE_CONTEXT_KEYWORDS = {
DEADLINE: "deadline",
START: "start",
END: "end",
EXPIR: "expir",
} as const
/**
* Context keywords for UUID detection
*/
export const UUID_CONTEXT_KEYWORDS = {
ID: "id",
IDENTIFIER: "identifier",
REQUEST: "request",
SESSION: "session",
} as const
/**
* Context keywords for version detection
*/
export const VERSION_CONTEXT_KEYWORDS = {
APP: "app",
} as const
/**
* Context keywords for color detection
*/
export const COLOR_CONTEXT_KEYWORDS = {
PRIMARY: "primary",
SECONDARY: "secondary",
BACKGROUND: "background",
} as const
/**
* Context keywords for base64 detection
*/
export const BASE64_CONTEXT_KEYWORDS = {
TOKEN: "token",
KEY: "key",
} as const
/**
* Context keywords for config detection
*/
export const CONFIG_CONTEXT_KEYWORDS = {
ENDPOINT: "endpoint",
ROUTE: "route",
CONNECTION: "connection",
} as const
/** /**
* Constant name templates * Constant name templates
*/ */
@@ -41,6 +141,50 @@ export const CONSTANT_NAMES = {
MAGIC_STRING: "MAGIC_STRING", MAGIC_STRING: "MAGIC_STRING",
MAGIC_NUMBER: "MAGIC_NUMBER", MAGIC_NUMBER: "MAGIC_NUMBER",
UNKNOWN_CONSTANT: "UNKNOWN_CONSTANT", UNKNOWN_CONSTANT: "UNKNOWN_CONSTANT",
ADMIN_EMAIL: "ADMIN_EMAIL",
SUPPORT_EMAIL: "SUPPORT_EMAIL",
NOREPLY_EMAIL: "NOREPLY_EMAIL",
DEFAULT_EMAIL: "DEFAULT_EMAIL",
API_SECRET_KEY: "API_SECRET_KEY",
API_PUBLIC_KEY: "API_PUBLIC_KEY",
API_KEY: "API_KEY",
DATABASE_URL: "DATABASE_URL",
MONGODB_CONNECTION_STRING: "MONGODB_CONNECTION_STRING",
POSTGRES_URL: "POSTGRES_URL",
BASE_URL: "BASE_URL",
SERVER_IP: "SERVER_IP",
DATABASE_HOST: "DATABASE_HOST",
REDIS_HOST: "REDIS_HOST",
HOST_IP: "HOST_IP",
LOG_FILE_PATH: "LOG_FILE_PATH",
CONFIG_FILE_PATH: "CONFIG_FILE_PATH",
DATA_DIR_PATH: "DATA_DIR_PATH",
TEMP_DIR_PATH: "TEMP_DIR_PATH",
FILE_PATH: "FILE_PATH",
DEADLINE: "DEADLINE",
START_DATE: "START_DATE",
END_DATE: "END_DATE",
EXPIRATION_DATE: "EXPIRATION_DATE",
DEFAULT_DATE: "DEFAULT_DATE",
DEFAULT_ID: "DEFAULT_ID",
REQUEST_ID: "REQUEST_ID",
SESSION_ID: "SESSION_ID",
UUID_CONSTANT: "UUID_CONSTANT",
API_VERSION: "API_VERSION",
APP_VERSION: "APP_VERSION",
VERSION: "VERSION",
PRIMARY_COLOR: "PRIMARY_COLOR",
SECONDARY_COLOR: "SECONDARY_COLOR",
BACKGROUND_COLOR: "BACKGROUND_COLOR",
COLOR_CONSTANT: "COLOR_CONSTANT",
MAC_ADDRESS: "MAC_ADDRESS",
ENCODED_TOKEN: "ENCODED_TOKEN",
ENCODED_KEY: "ENCODED_KEY",
BASE64_VALUE: "BASE64_VALUE",
API_ENDPOINT: "API_ENDPOINT",
ROUTE_PATH: "ROUTE_PATH",
CONNECTION_STRING: "CONNECTION_STRING",
CONFIG_VALUE: "CONFIG_VALUE",
} as const } as const
/** /**
@@ -50,4 +194,8 @@ export const LOCATIONS = {
SHARED_CONSTANTS: "shared/constants", SHARED_CONSTANTS: "shared/constants",
DOMAIN_CONSTANTS: "domain/constants", DOMAIN_CONSTANTS: "domain/constants",
INFRASTRUCTURE_CONFIG: "infrastructure/config", INFRASTRUCTURE_CONFIG: "infrastructure/config",
CONFIG_ENVIRONMENT: "src/config/environment.ts",
CONFIG_CONTACTS: "src/config/contacts.ts",
CONFIG_PATHS: "src/config/paths.ts",
CONFIG_DATES: "src/config/dates.ts",
} as const } as const

View File

@@ -1,6 +1,21 @@
import { ValueObject } from "./ValueObject" import { ValueObject } from "./ValueObject"
import { DETECTION_PATTERNS, HARDCODE_TYPES } from "../../shared/constants/rules" import { DETECTION_PATTERNS, HARDCODE_TYPES } from "../../shared/constants/rules"
import { CONSTANT_NAMES, LOCATIONS, SUGGESTION_KEYWORDS } from "../constants/Suggestions" import {
API_KEY_CONTEXT_KEYWORDS,
BASE64_CONTEXT_KEYWORDS,
COLOR_CONTEXT_KEYWORDS,
CONFIG_CONTEXT_KEYWORDS,
CONSTANT_NAMES,
DATE_CONTEXT_KEYWORDS,
EMAIL_CONTEXT_KEYWORDS,
FILE_PATH_CONTEXT_KEYWORDS,
IP_CONTEXT_KEYWORDS,
LOCATIONS,
SUGGESTION_KEYWORDS,
URL_CONTEXT_KEYWORDS,
UUID_CONTEXT_KEYWORDS,
VERSION_CONTEXT_KEYWORDS,
} from "../constants/Suggestions"
export type HardcodeType = (typeof HARDCODE_TYPES)[keyof typeof HARDCODE_TYPES] export type HardcodeType = (typeof HARDCODE_TYPES)[keyof typeof HARDCODE_TYPES]
@@ -162,150 +177,165 @@ export class HardcodedValue extends ValueObject<HardcodedValueProps> {
const valueType = this.props.valueType const valueType = this.props.valueType
if (valueType === "email") { if (valueType === "email") {
if (context.includes("admin")) { if (context.includes(EMAIL_CONTEXT_KEYWORDS.ADMIN)) {
return "ADMIN_EMAIL" return CONSTANT_NAMES.ADMIN_EMAIL
} }
if (context.includes("support")) { if (context.includes(EMAIL_CONTEXT_KEYWORDS.SUPPORT)) {
return "SUPPORT_EMAIL" return CONSTANT_NAMES.SUPPORT_EMAIL
} }
if (context.includes("noreply") || context.includes("no-reply")) { if (
return "NOREPLY_EMAIL" context.includes(EMAIL_CONTEXT_KEYWORDS.NOREPLY) ||
context.includes(EMAIL_CONTEXT_KEYWORDS.NO_REPLY)
) {
return CONSTANT_NAMES.NOREPLY_EMAIL
} }
return "DEFAULT_EMAIL" return CONSTANT_NAMES.DEFAULT_EMAIL
} }
if (valueType === "api_key") { if (valueType === "api_key") {
if (context.includes("secret")) { if (context.includes(API_KEY_CONTEXT_KEYWORDS.SECRET)) {
return "API_SECRET_KEY" return CONSTANT_NAMES.API_SECRET_KEY
} }
if (context.includes("public")) { if (context.includes(API_KEY_CONTEXT_KEYWORDS.PUBLIC)) {
return "API_PUBLIC_KEY" return CONSTANT_NAMES.API_PUBLIC_KEY
} }
return "API_KEY" return CONSTANT_NAMES.API_KEY
} }
if (valueType === "url") { if (valueType === "url") {
if (context.includes("api")) { if (context.includes(URL_CONTEXT_KEYWORDS.API)) {
return "API_BASE_URL" return CONSTANT_NAMES.API_BASE_URL
} }
if (context.includes("database") || context.includes("db")) { if (
return "DATABASE_URL" context.includes(URL_CONTEXT_KEYWORDS.DATABASE) ||
context.includes(URL_CONTEXT_KEYWORDS.DB)
) {
return CONSTANT_NAMES.DATABASE_URL
} }
if (context.includes("mongo")) { if (context.includes(URL_CONTEXT_KEYWORDS.MONGO)) {
return "MONGODB_CONNECTION_STRING" return CONSTANT_NAMES.MONGODB_CONNECTION_STRING
} }
if (context.includes("postgres") || context.includes("pg")) { if (
return "POSTGRES_URL" context.includes(URL_CONTEXT_KEYWORDS.POSTGRES) ||
context.includes(URL_CONTEXT_KEYWORDS.PG)
) {
return CONSTANT_NAMES.POSTGRES_URL
} }
return "BASE_URL" return CONSTANT_NAMES.BASE_URL
} }
if (valueType === "ip_address") { if (valueType === "ip_address") {
if (context.includes("server")) { if (context.includes(IP_CONTEXT_KEYWORDS.SERVER)) {
return "SERVER_IP" return CONSTANT_NAMES.SERVER_IP
} }
if (context.includes("database") || context.includes("db")) { if (
return "DATABASE_HOST" context.includes(URL_CONTEXT_KEYWORDS.DATABASE) ||
context.includes(URL_CONTEXT_KEYWORDS.DB)
) {
return CONSTANT_NAMES.DATABASE_HOST
} }
if (context.includes("redis")) { if (context.includes(IP_CONTEXT_KEYWORDS.REDIS)) {
return "REDIS_HOST" return CONSTANT_NAMES.REDIS_HOST
} }
return "HOST_IP" return CONSTANT_NAMES.HOST_IP
} }
if (valueType === "file_path") { if (valueType === "file_path") {
if (context.includes("log")) { if (context.includes(FILE_PATH_CONTEXT_KEYWORDS.LOG)) {
return "LOG_FILE_PATH" return CONSTANT_NAMES.LOG_FILE_PATH
} }
if (context.includes("config")) { if (context.includes(SUGGESTION_KEYWORDS.CONFIG)) {
return "CONFIG_FILE_PATH" return CONSTANT_NAMES.CONFIG_FILE_PATH
} }
if (context.includes("data")) { if (context.includes(FILE_PATH_CONTEXT_KEYWORDS.DATA)) {
return "DATA_DIR_PATH" return CONSTANT_NAMES.DATA_DIR_PATH
} }
if (context.includes("temp")) { if (context.includes(FILE_PATH_CONTEXT_KEYWORDS.TEMP)) {
return "TEMP_DIR_PATH" return CONSTANT_NAMES.TEMP_DIR_PATH
} }
return "FILE_PATH" return CONSTANT_NAMES.FILE_PATH
} }
if (valueType === "date") { if (valueType === "date") {
if (context.includes("deadline")) { if (context.includes(DATE_CONTEXT_KEYWORDS.DEADLINE)) {
return "DEADLINE" return CONSTANT_NAMES.DEADLINE
} }
if (context.includes("start")) { if (context.includes(DATE_CONTEXT_KEYWORDS.START)) {
return "START_DATE" return CONSTANT_NAMES.START_DATE
} }
if (context.includes("end")) { if (context.includes(DATE_CONTEXT_KEYWORDS.END)) {
return "END_DATE" return CONSTANT_NAMES.END_DATE
} }
if (context.includes("expir")) { if (context.includes(DATE_CONTEXT_KEYWORDS.EXPIR)) {
return "EXPIRATION_DATE" return CONSTANT_NAMES.EXPIRATION_DATE
} }
return "DEFAULT_DATE" return CONSTANT_NAMES.DEFAULT_DATE
} }
if (valueType === "uuid") { if (valueType === "uuid") {
if (context.includes("id") || context.includes("identifier")) { if (
return "DEFAULT_ID" context.includes(UUID_CONTEXT_KEYWORDS.ID) ||
context.includes(UUID_CONTEXT_KEYWORDS.IDENTIFIER)
) {
return CONSTANT_NAMES.DEFAULT_ID
} }
if (context.includes("request")) { if (context.includes(UUID_CONTEXT_KEYWORDS.REQUEST)) {
return "REQUEST_ID" return CONSTANT_NAMES.REQUEST_ID
} }
if (context.includes("session")) { if (context.includes(UUID_CONTEXT_KEYWORDS.SESSION)) {
return "SESSION_ID" return CONSTANT_NAMES.SESSION_ID
} }
return "UUID_CONSTANT" return CONSTANT_NAMES.UUID_CONSTANT
} }
if (valueType === "version") { if (valueType === "version") {
if (context.includes("api")) { if (context.includes(URL_CONTEXT_KEYWORDS.API)) {
return "API_VERSION" return CONSTANT_NAMES.API_VERSION
} }
if (context.includes("app")) { if (context.includes(VERSION_CONTEXT_KEYWORDS.APP)) {
return "APP_VERSION" return CONSTANT_NAMES.APP_VERSION
} }
return "VERSION" return CONSTANT_NAMES.VERSION
} }
if (valueType === "color") { if (valueType === "color") {
if (context.includes("primary")) { if (context.includes(COLOR_CONTEXT_KEYWORDS.PRIMARY)) {
return "PRIMARY_COLOR" return CONSTANT_NAMES.PRIMARY_COLOR
} }
if (context.includes("secondary")) { if (context.includes(COLOR_CONTEXT_KEYWORDS.SECONDARY)) {
return "SECONDARY_COLOR" return CONSTANT_NAMES.SECONDARY_COLOR
} }
if (context.includes("background")) { if (context.includes(COLOR_CONTEXT_KEYWORDS.BACKGROUND)) {
return "BACKGROUND_COLOR" return CONSTANT_NAMES.BACKGROUND_COLOR
} }
return "COLOR_CONSTANT" return CONSTANT_NAMES.COLOR_CONSTANT
} }
if (valueType === "mac_address") { if (valueType === "mac_address") {
return "MAC_ADDRESS" return CONSTANT_NAMES.MAC_ADDRESS
} }
if (valueType === "base64") { if (valueType === "base64") {
if (context.includes("token")) { if (context.includes(BASE64_CONTEXT_KEYWORDS.TOKEN)) {
return "ENCODED_TOKEN" return CONSTANT_NAMES.ENCODED_TOKEN
} }
if (context.includes("key")) { if (context.includes(BASE64_CONTEXT_KEYWORDS.KEY)) {
return "ENCODED_KEY" return CONSTANT_NAMES.ENCODED_KEY
} }
return "BASE64_VALUE" return CONSTANT_NAMES.BASE64_VALUE
} }
if (valueType === "config") { if (valueType === "config") {
if (context.includes("endpoint")) { if (context.includes(CONFIG_CONTEXT_KEYWORDS.ENDPOINT)) {
return "API_ENDPOINT" return CONSTANT_NAMES.API_ENDPOINT
} }
if (context.includes("route")) { if (context.includes(CONFIG_CONTEXT_KEYWORDS.ROUTE)) {
return "ROUTE_PATH" return CONSTANT_NAMES.ROUTE_PATH
} }
if (context.includes("connection")) { if (context.includes(CONFIG_CONTEXT_KEYWORDS.CONNECTION)) {
return "CONNECTION_STRING" return CONSTANT_NAMES.CONNECTION_STRING
} }
return "CONFIG_VALUE" return CONSTANT_NAMES.CONFIG_VALUE
} }
if (value.includes(SUGGESTION_KEYWORDS.HTTP)) { if (value.includes(SUGGESTION_KEYWORDS.HTTP)) {
@@ -339,19 +369,19 @@ export class HardcodedValue extends ValueObject<HardcodedValueProps> {
const valueType = this.props.valueType const valueType = this.props.valueType
if (valueType === "api_key" || valueType === "url" || valueType === "ip_address") { if (valueType === "api_key" || valueType === "url" || valueType === "ip_address") {
return "src/config/environment.ts" return LOCATIONS.CONFIG_ENVIRONMENT
} }
if (valueType === "email") { if (valueType === "email") {
return "src/config/contacts.ts" return LOCATIONS.CONFIG_CONTACTS
} }
if (valueType === "file_path") { if (valueType === "file_path") {
return "src/config/paths.ts" return LOCATIONS.CONFIG_PATHS
} }
if (valueType === "date") { if (valueType === "date") {
return "src/config/dates.ts" return LOCATIONS.CONFIG_DATES
} }
if ( if (