@webpieces/dev-config 0.2.80 → 0.2.82

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import { ReturnTypeMode } from '../validate-return-types/executor';
3
3
  import { NoInlineTypesMode } from '../validate-no-inline-types/executor';
4
4
  import { NoAnyUnknownMode } from '../validate-no-any-unknown/executor';
5
5
  import { ValidateDtosMode } from '../validate-dtos/executor';
6
+ import { PrismaConverterMode } from '../validate-prisma-converters/executor';
6
7
  export type MethodMaxLimitMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';
7
8
  export type FileMaxLimitMode = 'OFF' | 'MODIFIED_FILES';
8
9
  export interface MethodMaxLimitConfig {
@@ -22,6 +23,11 @@ export interface ValidateDtosConfig {
22
23
  prismaSchemaPath?: string;
23
24
  dtoSourcePaths?: string[];
24
25
  }
26
+ export interface PrismaConverterConfig {
27
+ mode?: PrismaConverterMode;
28
+ schemaPath?: string;
29
+ convertersPaths?: string[];
30
+ }
25
31
  export interface ValidateCodeOptions {
26
32
  methodMaxLimit?: MethodMaxLimitConfig;
27
33
  fileMaxLimit?: FileMaxLimitConfig;
@@ -29,6 +35,7 @@ export interface ValidateCodeOptions {
29
35
  noInlineTypeLiteralsMode?: NoInlineTypesMode;
30
36
  noAnyUnknownMode?: NoAnyUnknownMode;
31
37
  validateDtos?: ValidateDtosConfig;
38
+ prismaConverter?: PrismaConverterConfig;
32
39
  }
33
40
  export interface ExecutorResult {
34
41
  success: boolean;
@@ -9,6 +9,7 @@ const executor_4 = tslib_1.__importDefault(require("../validate-return-types/exe
9
9
  const executor_5 = tslib_1.__importDefault(require("../validate-no-inline-types/executor"));
10
10
  const executor_6 = tslib_1.__importDefault(require("../validate-no-any-unknown/executor"));
11
11
  const executor_7 = tslib_1.__importDefault(require("../validate-dtos/executor"));
12
+ const executor_8 = tslib_1.__importDefault(require("../validate-prisma-converters/executor"));
12
13
  function formatEpochDate(epoch) {
13
14
  return new Date(epoch * 1000).toISOString().split('T')[0];
14
15
  }
@@ -67,6 +68,9 @@ function parseConfig(options) {
67
68
  validateDtosMode: options.validateDtos?.mode ?? 'OFF',
68
69
  validateDtosPrismaPath: options.validateDtos?.prismaSchemaPath,
69
70
  validateDtosSrcPaths: options.validateDtos?.dtoSourcePaths ?? [],
71
+ prismaConverterMode: options.prismaConverter?.mode ?? 'OFF',
72
+ prismaConverterSchemaPath: options.prismaConverter?.schemaPath,
73
+ prismaConverterConvertersPaths: options.prismaConverter?.convertersPaths ?? [],
70
74
  };
71
75
  }
72
76
  function formatOverride(override) {
@@ -83,12 +87,14 @@ function logConfig(config) {
83
87
  console.log(` No inline type literals: ${config.noInlineTypesMode}`);
84
88
  console.log(` No any/unknown: ${config.noAnyUnknownMode}`);
85
89
  console.log(` Validate DTOs: ${config.validateDtosMode}`);
90
+ console.log(` Prisma converters: ${config.prismaConverterMode}`);
86
91
  console.log('');
87
92
  }
88
93
  function isAllOff(config) {
89
94
  return config.methodMode === 'OFF' && config.fileMode === 'OFF' &&
90
95
  config.returnTypeMode === 'OFF' && config.noInlineTypesMode === 'OFF' &&
91
- config.noAnyUnknownMode === 'OFF' && config.validateDtosMode === 'OFF';
96
+ config.noAnyUnknownMode === 'OFF' && config.validateDtosMode === 'OFF' &&
97
+ config.prismaConverterMode === 'OFF';
92
98
  }
93
99
  async function runMethodValidators(config, context) {
94
100
  const results = [];
@@ -126,10 +132,15 @@ async function runExecutor(options, context) {
126
132
  prismaSchemaPath: config.validateDtosPrismaPath,
127
133
  dtoSourcePaths: config.validateDtosSrcPaths,
128
134
  }, context);
135
+ const prismaConverterResult = await (0, executor_8.default)({
136
+ mode: config.prismaConverterMode,
137
+ schemaPath: config.prismaConverterSchemaPath,
138
+ convertersPaths: config.prismaConverterConvertersPaths,
139
+ }, context);
129
140
  const allSuccess = methodResults.every((r) => r.success) &&
130
141
  fileResult.success && returnTypesResult.success &&
131
142
  noInlineTypesResult.success && noAnyUnknownResult.success &&
132
- validateDtosResult.success;
143
+ validateDtosResult.success && prismaConverterResult.success;
133
144
  console.log(allSuccess ? '\n\u2705 All code validations passed\n' : '\n\u274c Some code validations failed\n');
134
145
  return { success: allSuccess };
135
146
  }
@@ -1 +1 @@
1
- {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-code/executor.ts"],"names":[],"mappings":"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","sourcesContent":["import { ExecutorContext } from '@nx/devkit';\nimport runNewMethodsExecutor from '../validate-new-methods/executor';\nimport runModifiedMethodsExecutor from '../validate-modified-methods/executor';\nimport runModifiedFilesExecutor from '../validate-modified-files/executor';\nimport runReturnTypesExecutor, { ReturnTypeMode } from '../validate-return-types/executor';\nimport runNoInlineTypesExecutor, { NoInlineTypesMode } from '../validate-no-inline-types/executor';\nimport runNoAnyUnknownExecutor, { NoAnyUnknownMode } from '../validate-no-any-unknown/executor';\nimport runValidateDtosExecutor, { ValidateDtosMode } from '../validate-dtos/executor';\n\nexport type MethodMaxLimitMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\nexport type FileMaxLimitMode = 'OFF' | 'MODIFIED_FILES';\n\nexport interface MethodMaxLimitConfig {\n limit?: number;\n mode?: MethodMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface FileMaxLimitConfig {\n limit?: number;\n mode?: FileMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ValidateDtosConfig {\n mode?: ValidateDtosMode;\n prismaSchemaPath?: string;\n dtoSourcePaths?: string[];\n}\n\nexport interface ValidateCodeOptions {\n methodMaxLimit?: MethodMaxLimitConfig;\n fileMaxLimit?: FileMaxLimitConfig;\n requireReturnTypeMode?: ReturnTypeMode;\n noInlineTypeLiteralsMode?: NoInlineTypesMode;\n noAnyUnknownMode?: NoAnyUnknownMode;\n validateDtos?: ValidateDtosConfig;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface OverrideInfo {\n active: boolean;\n normalMode: string;\n expiresDate: string;\n}\n\ninterface ParsedConfig {\n methodLimit: number;\n methodMode: MethodMaxLimitMode;\n methodDisableAllowed: boolean;\n methodOverride: OverrideInfo | undefined;\n fileLimit: number;\n fileMode: FileMaxLimitMode;\n fileDisableAllowed: boolean;\n fileOverride: OverrideInfo | undefined;\n returnTypeMode: ReturnTypeMode;\n noInlineTypesMode: NoInlineTypesMode;\n noAnyUnknownMode: NoAnyUnknownMode;\n validateDtosMode: ValidateDtosMode;\n validateDtosPrismaPath: string | undefined;\n validateDtosSrcPaths: string[];\n}\n\ninterface ResolvedMethodMode {\n mode: MethodMaxLimitMode;\n override: OverrideInfo | undefined;\n}\n\ninterface ResolvedFileMode {\n mode: FileMaxLimitMode;\n override: OverrideInfo | undefined;\n}\n\nfunction formatEpochDate(epoch: number): string {\n return new Date(epoch * 1000).toISOString().split('T')[0];\n}\n\nfunction resolveMethodMode(\n normalMode: MethodMaxLimitMode, epoch: number | undefined\n): ResolvedMethodMode {\n if (epoch === undefined) {\n return { mode: normalMode, override: undefined };\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n // Active: downgrade to skip modified checking\n const downgraded: MethodMaxLimitMode =\n normalMode === 'OFF' ? 'OFF' : 'NEW_METHODS';\n return {\n mode: downgraded,\n override: { active: true, normalMode, expiresDate: formatEpochDate(epoch) },\n };\n }\n // Expired\n console.log(`\\n\\u26a0\\ufe0f methodMaxLimit.ignoreModifiedUntilEpoch (${epoch}) has expired (${formatEpochDate(epoch)}). Remove it from nx.json. Using normal mode: ${normalMode}\\n`);\n return { mode: normalMode, override: undefined };\n}\n\nfunction resolveFileMode(\n normalMode: FileMaxLimitMode, epoch: number | undefined\n): ResolvedFileMode {\n if (epoch === undefined) {\n return { mode: normalMode, override: undefined };\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n // Active: file checking is inherently about modified files, so skip entirely\n return {\n mode: 'OFF',\n override: { active: true, normalMode, expiresDate: formatEpochDate(epoch) },\n };\n }\n // Expired\n console.log(`\\n\\u26a0\\ufe0f fileMaxLimit.ignoreModifiedUntilEpoch (${epoch}) has expired (${formatEpochDate(epoch)}). Remove it from nx.json. Using normal mode: ${normalMode}\\n`);\n return { mode: normalMode, override: undefined };\n}\n\nfunction parseConfig(options: ValidateCodeOptions): ParsedConfig {\n const methodConfig: MethodMaxLimitConfig = options.methodMaxLimit ?? {};\n const fileConfig: FileMaxLimitConfig = options.fileMaxLimit ?? {};\n\n const normalMethodMode = methodConfig.mode ?? 'NEW_AND_MODIFIED_METHODS';\n const normalFileMode = fileConfig.mode ?? 'MODIFIED_FILES';\n\n const methodResolved = resolveMethodMode(normalMethodMode, methodConfig.ignoreModifiedUntilEpoch);\n const fileResolved = resolveFileMode(normalFileMode, fileConfig.ignoreModifiedUntilEpoch);\n\n return {\n methodLimit: methodConfig.limit ?? 80,\n methodMode: methodResolved.mode,\n methodDisableAllowed: methodConfig.disableAllowed ?? true,\n methodOverride: methodResolved.override,\n fileLimit: fileConfig.limit ?? 900,\n fileMode: fileResolved.mode,\n fileDisableAllowed: fileConfig.disableAllowed ?? true,\n fileOverride: fileResolved.override,\n returnTypeMode: options.requireReturnTypeMode ?? 'OFF',\n noInlineTypesMode: options.noInlineTypeLiteralsMode ?? 'OFF',\n noAnyUnknownMode: options.noAnyUnknownMode ?? 'OFF',\n validateDtosMode: options.validateDtos?.mode ?? 'OFF',\n validateDtosPrismaPath: options.validateDtos?.prismaSchemaPath,\n validateDtosSrcPaths: options.validateDtos?.dtoSourcePaths ?? [],\n };\n}\n\nfunction formatOverride(override: OverrideInfo | undefined): string {\n if (!override) {\n return '';\n }\n return ` (override active, normal: ${override.normalMode}, expires: ${override.expiresDate})`;\n}\n\nfunction logConfig(config: ParsedConfig): void {\n console.log('\\n\\ud83d\\udccf Running Code Validations\\n');\n console.log(` Method limits: mode=${config.methodMode}${formatOverride(config.methodOverride)}, limit=${config.methodLimit}, disableAllowed=${config.methodDisableAllowed}`);\n console.log(` File limits: mode=${config.fileMode}${formatOverride(config.fileOverride)}, limit=${config.fileLimit}, disableAllowed=${config.fileDisableAllowed}`);\n console.log(` Require return types: ${config.returnTypeMode}`);\n console.log(` No inline type literals: ${config.noInlineTypesMode}`);\n console.log(` No any/unknown: ${config.noAnyUnknownMode}`);\n console.log(` Validate DTOs: ${config.validateDtosMode}`);\n console.log('');\n}\n\nfunction isAllOff(config: ParsedConfig): boolean {\n return config.methodMode === 'OFF' && config.fileMode === 'OFF' &&\n config.returnTypeMode === 'OFF' && config.noInlineTypesMode === 'OFF' &&\n config.noAnyUnknownMode === 'OFF' && config.validateDtosMode === 'OFF';\n}\n\nasync function runMethodValidators(config: ParsedConfig, context: ExecutorContext): Promise<ExecutorResult[]> {\n const results: ExecutorResult[] = [];\n const runNew = config.methodMode === 'NEW_METHODS' || config.methodMode === 'NEW_AND_MODIFIED_METHODS';\n const runModified = config.methodMode === 'NEW_AND_MODIFIED_METHODS' || config.methodMode === 'MODIFIED_FILES';\n\n if (runNew) {\n results.push(await runNewMethodsExecutor({\n limit: config.methodLimit,\n mode: config.methodMode, disableAllowed: config.methodDisableAllowed,\n }, context));\n }\n if (runModified) {\n results.push(await runModifiedMethodsExecutor({\n limit: config.methodLimit, mode: config.methodMode, disableAllowed: config.methodDisableAllowed,\n }, context));\n }\n return results;\n}\n\nexport default async function runExecutor(\n options: ValidateCodeOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const config = parseConfig(options);\n\n if (isAllOff(config)) {\n console.log('\\n\\u23ed\\ufe0f Skipping all code validations (all modes: OFF)\\n');\n return { success: true };\n }\n\n logConfig(config);\n\n const methodResults = await runMethodValidators(config, context);\n const fileResult = await runModifiedFilesExecutor({\n limit: config.fileLimit, mode: config.fileMode, disableAllowed: config.fileDisableAllowed,\n }, context);\n const returnTypesResult = await runReturnTypesExecutor({ mode: config.returnTypeMode }, context);\n const noInlineTypesResult = await runNoInlineTypesExecutor({ mode: config.noInlineTypesMode }, context);\n const noAnyUnknownResult = await runNoAnyUnknownExecutor({ mode: config.noAnyUnknownMode }, context);\n const validateDtosResult = await runValidateDtosExecutor({\n mode: config.validateDtosMode,\n prismaSchemaPath: config.validateDtosPrismaPath,\n dtoSourcePaths: config.validateDtosSrcPaths,\n }, context);\n\n const allSuccess = methodResults.every((r) => r.success) &&\n fileResult.success && returnTypesResult.success &&\n noInlineTypesResult.success && noAnyUnknownResult.success &&\n validateDtosResult.success;\n\n console.log(allSuccess ? '\\n\\u2705 All code validations passed\\n' : '\\n\\u274c Some code validations failed\\n');\n return { success: allSuccess };\n}\n"]}
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../../packages/tooling/dev-config/architecture/executors/validate-code/executor.ts"],"names":[],"mappings":"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","sourcesContent":["import { ExecutorContext } from '@nx/devkit';\nimport runNewMethodsExecutor from '../validate-new-methods/executor';\nimport runModifiedMethodsExecutor from '../validate-modified-methods/executor';\nimport runModifiedFilesExecutor from '../validate-modified-files/executor';\nimport runReturnTypesExecutor, { ReturnTypeMode } from '../validate-return-types/executor';\nimport runNoInlineTypesExecutor, { NoInlineTypesMode } from '../validate-no-inline-types/executor';\nimport runNoAnyUnknownExecutor, { NoAnyUnknownMode } from '../validate-no-any-unknown/executor';\nimport runValidateDtosExecutor, { ValidateDtosMode } from '../validate-dtos/executor';\nimport runPrismaConvertersExecutor, { PrismaConverterMode } from '../validate-prisma-converters/executor';\n\nexport type MethodMaxLimitMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\nexport type FileMaxLimitMode = 'OFF' | 'MODIFIED_FILES';\n\nexport interface MethodMaxLimitConfig {\n limit?: number;\n mode?: MethodMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface FileMaxLimitConfig {\n limit?: number;\n mode?: FileMaxLimitMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ValidateDtosConfig {\n mode?: ValidateDtosMode;\n prismaSchemaPath?: string;\n dtoSourcePaths?: string[];\n}\n\nexport interface PrismaConverterConfig {\n mode?: PrismaConverterMode;\n schemaPath?: string;\n convertersPaths?: string[];\n}\n\nexport interface ValidateCodeOptions {\n methodMaxLimit?: MethodMaxLimitConfig;\n fileMaxLimit?: FileMaxLimitConfig;\n requireReturnTypeMode?: ReturnTypeMode;\n noInlineTypeLiteralsMode?: NoInlineTypesMode;\n noAnyUnknownMode?: NoAnyUnknownMode;\n validateDtos?: ValidateDtosConfig;\n prismaConverter?: PrismaConverterConfig;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface OverrideInfo {\n active: boolean;\n normalMode: string;\n expiresDate: string;\n}\n\ninterface ParsedConfig {\n methodLimit: number;\n methodMode: MethodMaxLimitMode;\n methodDisableAllowed: boolean;\n methodOverride: OverrideInfo | undefined;\n fileLimit: number;\n fileMode: FileMaxLimitMode;\n fileDisableAllowed: boolean;\n fileOverride: OverrideInfo | undefined;\n returnTypeMode: ReturnTypeMode;\n noInlineTypesMode: NoInlineTypesMode;\n noAnyUnknownMode: NoAnyUnknownMode;\n validateDtosMode: ValidateDtosMode;\n validateDtosPrismaPath: string | undefined;\n validateDtosSrcPaths: string[];\n prismaConverterMode: PrismaConverterMode;\n prismaConverterSchemaPath: string | undefined;\n prismaConverterConvertersPaths: string[];\n}\n\ninterface ResolvedMethodMode {\n mode: MethodMaxLimitMode;\n override: OverrideInfo | undefined;\n}\n\ninterface ResolvedFileMode {\n mode: FileMaxLimitMode;\n override: OverrideInfo | undefined;\n}\n\nfunction formatEpochDate(epoch: number): string {\n return new Date(epoch * 1000).toISOString().split('T')[0];\n}\n\nfunction resolveMethodMode(\n normalMode: MethodMaxLimitMode, epoch: number | undefined\n): ResolvedMethodMode {\n if (epoch === undefined) {\n return { mode: normalMode, override: undefined };\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n // Active: downgrade to skip modified checking\n const downgraded: MethodMaxLimitMode =\n normalMode === 'OFF' ? 'OFF' : 'NEW_METHODS';\n return {\n mode: downgraded,\n override: { active: true, normalMode, expiresDate: formatEpochDate(epoch) },\n };\n }\n // Expired\n console.log(`\\n\\u26a0\\ufe0f methodMaxLimit.ignoreModifiedUntilEpoch (${epoch}) has expired (${formatEpochDate(epoch)}). Remove it from nx.json. Using normal mode: ${normalMode}\\n`);\n return { mode: normalMode, override: undefined };\n}\n\nfunction resolveFileMode(\n normalMode: FileMaxLimitMode, epoch: number | undefined\n): ResolvedFileMode {\n if (epoch === undefined) {\n return { mode: normalMode, override: undefined };\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n // Active: file checking is inherently about modified files, so skip entirely\n return {\n mode: 'OFF',\n override: { active: true, normalMode, expiresDate: formatEpochDate(epoch) },\n };\n }\n // Expired\n console.log(`\\n\\u26a0\\ufe0f fileMaxLimit.ignoreModifiedUntilEpoch (${epoch}) has expired (${formatEpochDate(epoch)}). Remove it from nx.json. Using normal mode: ${normalMode}\\n`);\n return { mode: normalMode, override: undefined };\n}\n\nfunction parseConfig(options: ValidateCodeOptions): ParsedConfig {\n const methodConfig: MethodMaxLimitConfig = options.methodMaxLimit ?? {};\n const fileConfig: FileMaxLimitConfig = options.fileMaxLimit ?? {};\n\n const normalMethodMode = methodConfig.mode ?? 'NEW_AND_MODIFIED_METHODS';\n const normalFileMode = fileConfig.mode ?? 'MODIFIED_FILES';\n\n const methodResolved = resolveMethodMode(normalMethodMode, methodConfig.ignoreModifiedUntilEpoch);\n const fileResolved = resolveFileMode(normalFileMode, fileConfig.ignoreModifiedUntilEpoch);\n\n return {\n methodLimit: methodConfig.limit ?? 80,\n methodMode: methodResolved.mode,\n methodDisableAllowed: methodConfig.disableAllowed ?? true,\n methodOverride: methodResolved.override,\n fileLimit: fileConfig.limit ?? 900,\n fileMode: fileResolved.mode,\n fileDisableAllowed: fileConfig.disableAllowed ?? true,\n fileOverride: fileResolved.override,\n returnTypeMode: options.requireReturnTypeMode ?? 'OFF',\n noInlineTypesMode: options.noInlineTypeLiteralsMode ?? 'OFF',\n noAnyUnknownMode: options.noAnyUnknownMode ?? 'OFF',\n validateDtosMode: options.validateDtos?.mode ?? 'OFF',\n validateDtosPrismaPath: options.validateDtos?.prismaSchemaPath,\n validateDtosSrcPaths: options.validateDtos?.dtoSourcePaths ?? [],\n prismaConverterMode: options.prismaConverter?.mode ?? 'OFF',\n prismaConverterSchemaPath: options.prismaConverter?.schemaPath,\n prismaConverterConvertersPaths: options.prismaConverter?.convertersPaths ?? [],\n };\n}\n\nfunction formatOverride(override: OverrideInfo | undefined): string {\n if (!override) {\n return '';\n }\n return ` (override active, normal: ${override.normalMode}, expires: ${override.expiresDate})`;\n}\n\nfunction logConfig(config: ParsedConfig): void {\n console.log('\\n\\ud83d\\udccf Running Code Validations\\n');\n console.log(` Method limits: mode=${config.methodMode}${formatOverride(config.methodOverride)}, limit=${config.methodLimit}, disableAllowed=${config.methodDisableAllowed}`);\n console.log(` File limits: mode=${config.fileMode}${formatOverride(config.fileOverride)}, limit=${config.fileLimit}, disableAllowed=${config.fileDisableAllowed}`);\n console.log(` Require return types: ${config.returnTypeMode}`);\n console.log(` No inline type literals: ${config.noInlineTypesMode}`);\n console.log(` No any/unknown: ${config.noAnyUnknownMode}`);\n console.log(` Validate DTOs: ${config.validateDtosMode}`);\n console.log(` Prisma converters: ${config.prismaConverterMode}`);\n console.log('');\n}\n\nfunction isAllOff(config: ParsedConfig): boolean {\n return config.methodMode === 'OFF' && config.fileMode === 'OFF' &&\n config.returnTypeMode === 'OFF' && config.noInlineTypesMode === 'OFF' &&\n config.noAnyUnknownMode === 'OFF' && config.validateDtosMode === 'OFF' &&\n config.prismaConverterMode === 'OFF';\n}\n\nasync function runMethodValidators(config: ParsedConfig, context: ExecutorContext): Promise<ExecutorResult[]> {\n const results: ExecutorResult[] = [];\n const runNew = config.methodMode === 'NEW_METHODS' || config.methodMode === 'NEW_AND_MODIFIED_METHODS';\n const runModified = config.methodMode === 'NEW_AND_MODIFIED_METHODS' || config.methodMode === 'MODIFIED_FILES';\n\n if (runNew) {\n results.push(await runNewMethodsExecutor({\n limit: config.methodLimit,\n mode: config.methodMode, disableAllowed: config.methodDisableAllowed,\n }, context));\n }\n if (runModified) {\n results.push(await runModifiedMethodsExecutor({\n limit: config.methodLimit, mode: config.methodMode, disableAllowed: config.methodDisableAllowed,\n }, context));\n }\n return results;\n}\n\nexport default async function runExecutor(\n options: ValidateCodeOptions,\n context: ExecutorContext\n): Promise<ExecutorResult> {\n const config = parseConfig(options);\n\n if (isAllOff(config)) {\n console.log('\\n\\u23ed\\ufe0f Skipping all code validations (all modes: OFF)\\n');\n return { success: true };\n }\n\n logConfig(config);\n\n const methodResults = await runMethodValidators(config, context);\n const fileResult = await runModifiedFilesExecutor({\n limit: config.fileLimit, mode: config.fileMode, disableAllowed: config.fileDisableAllowed,\n }, context);\n const returnTypesResult = await runReturnTypesExecutor({ mode: config.returnTypeMode }, context);\n const noInlineTypesResult = await runNoInlineTypesExecutor({ mode: config.noInlineTypesMode }, context);\n const noAnyUnknownResult = await runNoAnyUnknownExecutor({ mode: config.noAnyUnknownMode }, context);\n const validateDtosResult = await runValidateDtosExecutor({\n mode: config.validateDtosMode,\n prismaSchemaPath: config.validateDtosPrismaPath,\n dtoSourcePaths: config.validateDtosSrcPaths,\n }, context);\n const prismaConverterResult = await runPrismaConvertersExecutor({\n mode: config.prismaConverterMode,\n schemaPath: config.prismaConverterSchemaPath,\n convertersPaths: config.prismaConverterConvertersPaths,\n }, context);\n\n const allSuccess = methodResults.every((r) => r.success) &&\n fileResult.success && returnTypesResult.success &&\n noInlineTypesResult.success && noAnyUnknownResult.success &&\n validateDtosResult.success && prismaConverterResult.success;\n\n console.log(allSuccess ? '\\n\\u2705 All code validations passed\\n' : '\\n\\u274c Some code validations failed\\n');\n return { success: allSuccess };\n}\n"]}
@@ -6,6 +6,7 @@ import runReturnTypesExecutor, { ReturnTypeMode } from '../validate-return-types
6
6
  import runNoInlineTypesExecutor, { NoInlineTypesMode } from '../validate-no-inline-types/executor';
7
7
  import runNoAnyUnknownExecutor, { NoAnyUnknownMode } from '../validate-no-any-unknown/executor';
8
8
  import runValidateDtosExecutor, { ValidateDtosMode } from '../validate-dtos/executor';
9
+ import runPrismaConvertersExecutor, { PrismaConverterMode } from '../validate-prisma-converters/executor';
9
10
 
10
11
  export type MethodMaxLimitMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';
11
12
  export type FileMaxLimitMode = 'OFF' | 'MODIFIED_FILES';
@@ -30,6 +31,12 @@ export interface ValidateDtosConfig {
30
31
  dtoSourcePaths?: string[];
31
32
  }
32
33
 
34
+ export interface PrismaConverterConfig {
35
+ mode?: PrismaConverterMode;
36
+ schemaPath?: string;
37
+ convertersPaths?: string[];
38
+ }
39
+
33
40
  export interface ValidateCodeOptions {
34
41
  methodMaxLimit?: MethodMaxLimitConfig;
35
42
  fileMaxLimit?: FileMaxLimitConfig;
@@ -37,6 +44,7 @@ export interface ValidateCodeOptions {
37
44
  noInlineTypeLiteralsMode?: NoInlineTypesMode;
38
45
  noAnyUnknownMode?: NoAnyUnknownMode;
39
46
  validateDtos?: ValidateDtosConfig;
47
+ prismaConverter?: PrismaConverterConfig;
40
48
  }
41
49
 
42
50
  export interface ExecutorResult {
@@ -64,6 +72,9 @@ interface ParsedConfig {
64
72
  validateDtosMode: ValidateDtosMode;
65
73
  validateDtosPrismaPath: string | undefined;
66
74
  validateDtosSrcPaths: string[];
75
+ prismaConverterMode: PrismaConverterMode;
76
+ prismaConverterSchemaPath: string | undefined;
77
+ prismaConverterConvertersPaths: string[];
67
78
  }
68
79
 
69
80
  interface ResolvedMethodMode {
@@ -145,6 +156,9 @@ function parseConfig(options: ValidateCodeOptions): ParsedConfig {
145
156
  validateDtosMode: options.validateDtos?.mode ?? 'OFF',
146
157
  validateDtosPrismaPath: options.validateDtos?.prismaSchemaPath,
147
158
  validateDtosSrcPaths: options.validateDtos?.dtoSourcePaths ?? [],
159
+ prismaConverterMode: options.prismaConverter?.mode ?? 'OFF',
160
+ prismaConverterSchemaPath: options.prismaConverter?.schemaPath,
161
+ prismaConverterConvertersPaths: options.prismaConverter?.convertersPaths ?? [],
148
162
  };
149
163
  }
150
164
 
@@ -163,13 +177,15 @@ function logConfig(config: ParsedConfig): void {
163
177
  console.log(` No inline type literals: ${config.noInlineTypesMode}`);
164
178
  console.log(` No any/unknown: ${config.noAnyUnknownMode}`);
165
179
  console.log(` Validate DTOs: ${config.validateDtosMode}`);
180
+ console.log(` Prisma converters: ${config.prismaConverterMode}`);
166
181
  console.log('');
167
182
  }
168
183
 
169
184
  function isAllOff(config: ParsedConfig): boolean {
170
185
  return config.methodMode === 'OFF' && config.fileMode === 'OFF' &&
171
186
  config.returnTypeMode === 'OFF' && config.noInlineTypesMode === 'OFF' &&
172
- config.noAnyUnknownMode === 'OFF' && config.validateDtosMode === 'OFF';
187
+ config.noAnyUnknownMode === 'OFF' && config.validateDtosMode === 'OFF' &&
188
+ config.prismaConverterMode === 'OFF';
173
189
  }
174
190
 
175
191
  async function runMethodValidators(config: ParsedConfig, context: ExecutorContext): Promise<ExecutorResult[]> {
@@ -216,11 +232,16 @@ export default async function runExecutor(
216
232
  prismaSchemaPath: config.validateDtosPrismaPath,
217
233
  dtoSourcePaths: config.validateDtosSrcPaths,
218
234
  }, context);
235
+ const prismaConverterResult = await runPrismaConvertersExecutor({
236
+ mode: config.prismaConverterMode,
237
+ schemaPath: config.prismaConverterSchemaPath,
238
+ convertersPaths: config.prismaConverterConvertersPaths,
239
+ }, context);
219
240
 
220
241
  const allSuccess = methodResults.every((r) => r.success) &&
221
242
  fileResult.success && returnTypesResult.success &&
222
243
  noInlineTypesResult.success && noAnyUnknownResult.success &&
223
- validateDtosResult.success;
244
+ validateDtosResult.success && prismaConverterResult.success;
224
245
 
225
246
  console.log(allSuccess ? '\n\u2705 All code validations passed\n' : '\n\u274c Some code validations failed\n');
226
247
  return { success: allSuccess };
@@ -80,8 +80,8 @@
80
80
  "properties": {
81
81
  "mode": {
82
82
  "type": "string",
83
- "enum": ["OFF", "MODIFIED_FILES"],
84
- "description": "OFF: skip validation. MODIFIED_FILES: validate Dto files that were modified in the diff.",
83
+ "enum": ["OFF", "MODIFIED_CLASS", "MODIFIED_FILES"],
84
+ "description": "OFF: skip validation. MODIFIED_CLASS: only validate Dto classes with changed lines. MODIFIED_FILES: validate all Dtos in modified files.",
85
85
  "default": "OFF"
86
86
  },
87
87
  "prismaSchemaPath": {
@@ -94,6 +94,27 @@
94
94
  "description": "Array of directories (relative to workspace root) containing Dto files"
95
95
  }
96
96
  }
97
+ },
98
+ "prismaConverter": {
99
+ "type": "object",
100
+ "description": "Validate Prisma converter methods follow scalable patterns: correct Dbo parameter, no async, no standalone functions, Dto creation only in converter directories.",
101
+ "properties": {
102
+ "mode": {
103
+ "type": "string",
104
+ "enum": ["OFF", "MODIFIED_FILES"],
105
+ "description": "OFF: skip validation. MODIFIED_FILES: validate converter and non-converter files modified in the diff.",
106
+ "default": "OFF"
107
+ },
108
+ "schemaPath": {
109
+ "type": "string",
110
+ "description": "Relative path from workspace root to schema.prisma"
111
+ },
112
+ "convertersPaths": {
113
+ "type": "array",
114
+ "items": { "type": "string" },
115
+ "description": "Array of directories (relative to workspace root) containing converter files"
116
+ }
117
+ }
97
118
  }
98
119
  },
99
120
  "required": []
@@ -9,7 +9,8 @@
9
9
  * MODES
10
10
  * ============================================================================
11
11
  * - OFF: Skip validation entirely
12
- * - MODIFIED_FILES: Validate Dto files that were modified in the diff
12
+ * - MODIFIED_CLASS: Only validate Dto classes that have changed lines in the diff
13
+ * - MODIFIED_FILES: Validate ALL Dto classes in files that were modified
13
14
  *
14
15
  * ============================================================================
15
16
  * SKIP CONDITIONS
@@ -22,11 +23,12 @@
22
23
  * MATCHING
23
24
  * ============================================================================
24
25
  * - UserDto matches UserDbo by case-insensitive prefix ("user")
26
+ * - Dbo field names are converted from snake_case to camelCase for comparison
25
27
  * - Dto fields must be a subset of Dbo fields
26
28
  * - Extra Dbo fields are allowed (e.g., password)
27
29
  */
28
30
  import type { ExecutorContext } from '@nx/devkit';
29
- export type ValidateDtosMode = 'OFF' | 'MODIFIED_FILES';
31
+ export type ValidateDtosMode = 'OFF' | 'MODIFIED_CLASS' | 'MODIFIED_FILES';
30
32
  export interface ValidateDtosOptions {
31
33
  mode?: ValidateDtosMode;
32
34
  prismaSchemaPath?: string;
@@ -10,7 +10,8 @@
10
10
  * MODES
11
11
  * ============================================================================
12
12
  * - OFF: Skip validation entirely
13
- * - MODIFIED_FILES: Validate Dto files that were modified in the diff
13
+ * - MODIFIED_CLASS: Only validate Dto classes that have changed lines in the diff
14
+ * - MODIFIED_FILES: Validate ALL Dto classes in files that were modified
14
15
  *
15
16
  * ============================================================================
16
17
  * SKIP CONDITIONS
@@ -23,6 +24,7 @@
23
24
  * MATCHING
24
25
  * ============================================================================
25
26
  * - UserDto matches UserDbo by case-insensitive prefix ("user")
27
+ * - Dbo field names are converted from snake_case to camelCase for comparison
26
28
  * - Dto fields must be a subset of Dbo fields
27
29
  * - Extra Dbo fields are allowed (e.g., password)
28
30
  */
@@ -103,8 +105,72 @@ function getChangedFiles(workspaceRoot, base, head) {
103
105
  }
104
106
  }
105
107
  /**
106
- * Parse schema.prisma to build a map of Dbo model name -> set of field names.
108
+ * Get the diff content for a specific file.
109
+ */
110
+ function getFileDiff(workspaceRoot, file, base, head) {
111
+ try {
112
+ const diffTarget = head ? `${base} ${head}` : base;
113
+ const diff = (0, child_process_1.execSync)(`git diff ${diffTarget} -- "${file}"`, {
114
+ cwd: workspaceRoot,
115
+ encoding: 'utf-8',
116
+ });
117
+ if (!diff && !head) {
118
+ const fullPath = path.join(workspaceRoot, file);
119
+ if (fs.existsSync(fullPath)) {
120
+ const isUntracked = (0, child_process_1.execSync)(`git ls-files --others --exclude-standard "${file}"`, {
121
+ cwd: workspaceRoot,
122
+ encoding: 'utf-8',
123
+ }).trim();
124
+ if (isUntracked) {
125
+ const content = fs.readFileSync(fullPath, 'utf-8');
126
+ const lines = content.split('\n');
127
+ return lines.map((line) => `+${line}`).join('\n');
128
+ }
129
+ }
130
+ }
131
+ return diff;
132
+ }
133
+ catch {
134
+ return '';
135
+ }
136
+ }
137
+ /**
138
+ * Parse diff to extract changed line numbers (additions only - lines starting with +).
139
+ */
140
+ function getChangedLineNumbers(diffContent) {
141
+ const changedLines = new Set();
142
+ const lines = diffContent.split('\n');
143
+ let currentLine = 0;
144
+ for (const line of lines) {
145
+ const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
146
+ if (hunkMatch) {
147
+ currentLine = parseInt(hunkMatch[1], 10);
148
+ continue;
149
+ }
150
+ if (line.startsWith('+') && !line.startsWith('+++')) {
151
+ changedLines.add(currentLine);
152
+ currentLine++;
153
+ }
154
+ else if (line.startsWith('-') && !line.startsWith('---')) {
155
+ // Deletions don't increment line number
156
+ }
157
+ else {
158
+ currentLine++;
159
+ }
160
+ }
161
+ return changedLines;
162
+ }
163
+ /**
164
+ * Convert a snake_case string to camelCase.
165
+ * e.g., "version_number" -> "versionNumber", "id" -> "id"
166
+ */
167
+ function snakeToCamel(s) {
168
+ return s.replace(/_([a-z])/g, (_, letter) => letter.toUpperCase());
169
+ }
170
+ /**
171
+ * Parse schema.prisma to build a map of Dbo model name -> set of field names (camelCase).
107
172
  * Only models whose name ends with "Dbo" are included.
173
+ * Field names are converted from snake_case to camelCase since Dto fields use camelCase.
108
174
  */
109
175
  function parsePrismaSchema(schemaPath) {
110
176
  const models = new Map();
@@ -137,10 +203,10 @@ function parsePrismaSchema(schemaPath) {
137
203
  if (!trimmed || trimmed.startsWith('//') || trimmed.startsWith('@@')) {
138
204
  continue;
139
205
  }
140
- // Field name is the first word on the line
206
+ // Field name is the first word on the line, converted to camelCase
141
207
  const fieldMatch = trimmed.match(/^(\w+)\s/);
142
208
  if (fieldMatch) {
143
- currentFields.add(fieldMatch[1]);
209
+ currentFields.add(snakeToCamel(fieldMatch[1]));
144
210
  }
145
211
  }
146
212
  }
@@ -179,6 +245,8 @@ function findDtosInFile(filePath, workspaceRoot) {
179
245
  // Must end with Dto but NOT with JoinDto
180
246
  if (name.endsWith('Dto') && !name.endsWith('JoinDto')) {
181
247
  const fields = [];
248
+ const nodeStart = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
249
+ const nodeEnd = sourceFile.getLineAndCharacterOfPosition(node.getEnd());
182
250
  for (const member of node.members) {
183
251
  if (ts.isPropertyDeclaration(member) || ts.isPropertySignature(member)) {
184
252
  if (member.name && ts.isIdentifier(member.name)) {
@@ -191,7 +259,13 @@ function findDtosInFile(filePath, workspaceRoot) {
191
259
  }
192
260
  }
193
261
  }
194
- dtos.push({ name, file: filePath, fields });
262
+ dtos.push({
263
+ name,
264
+ file: filePath,
265
+ startLine: nodeStart.line + 1,
266
+ endLine: nodeEnd.line + 1,
267
+ fields,
268
+ });
195
269
  }
196
270
  }
197
271
  ts.forEachChild(node, visit);
@@ -258,7 +332,7 @@ function reportViolations(violations) {
258
332
  console.error(` Available Dbo fields: ${v.availableFields.join(', ')}`);
259
333
  }
260
334
  console.error('');
261
- console.error(' Dto fields must be a subset of Dbo fields (matching TypeScript field names from schema.prisma).');
335
+ console.error(' Dto fields must be a subset of Dbo fields (matching camelCase field names).');
262
336
  console.error(' Fields marked @deprecated in the Dto are exempt from this check.');
263
337
  console.error('');
264
338
  console.error(' When needing fields from multiple tables (e.g., a join), use a XxxJoinDto that');
@@ -288,6 +362,39 @@ function collectDtos(dtoFiles, workspaceRoot) {
288
362
  }
289
363
  return allDtos;
290
364
  }
365
+ /**
366
+ * Check if a Dto class overlaps with any changed lines in the diff.
367
+ */
368
+ function isDtoTouched(dto, changedLines) {
369
+ for (let line = dto.startLine; line <= dto.endLine; line++) {
370
+ if (changedLines.has(line))
371
+ return true;
372
+ }
373
+ return false;
374
+ }
375
+ /**
376
+ * Filter Dtos to only those that have changed lines in the diff (MODIFIED_CLASS mode).
377
+ */
378
+ function filterTouchedDtos(dtos, workspaceRoot, base, head) {
379
+ // Group dtos by file to avoid re-fetching diffs
380
+ const byFile = new Map();
381
+ for (const dto of dtos) {
382
+ const list = byFile.get(dto.file) ?? [];
383
+ list.push(dto);
384
+ byFile.set(dto.file, list);
385
+ }
386
+ const touched = [];
387
+ for (const [file, fileDtos] of byFile) {
388
+ const diff = getFileDiff(workspaceRoot, file, base, head);
389
+ const changedLines = getChangedLineNumbers(diff);
390
+ for (const dto of fileDtos) {
391
+ if (isDtoTouched(dto, changedLines)) {
392
+ touched.push(dto);
393
+ }
394
+ }
395
+ }
396
+ return touched;
397
+ }
291
398
  /**
292
399
  * Resolve git base ref from env vars or auto-detection.
293
400
  */
@@ -300,7 +407,8 @@ function resolveBase(workspaceRoot) {
300
407
  /**
301
408
  * Run the core validation after early-exit checks have passed.
302
409
  */
303
- function validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSourcePaths) {
410
+ // webpieces-disable max-lines-new-methods -- Core validation orchestration with multiple early-exit checks
411
+ function validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSourcePaths, mode, base, head) {
304
412
  if (changedFiles.some((f) => f.endsWith(prismaSchemaPath))) {
305
413
  console.log('⏭️ Skipping validate-dtos (schema.prisma is modified - schema in flux)');
306
414
  console.log('');
@@ -320,12 +428,20 @@ function validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSour
320
428
  return { success: true };
321
429
  }
322
430
  console.log(` Found ${dboModels.size} Dbo model(s) in schema.prisma`);
323
- const allDtos = collectDtos(dtoFiles, workspaceRoot);
431
+ let allDtos = collectDtos(dtoFiles, workspaceRoot);
324
432
  if (allDtos.length === 0) {
325
433
  console.log('✅ No Dto definitions found in changed files');
326
434
  return { success: true };
327
435
  }
328
- console.log(` Found ${allDtos.length} Dto definition(s) in changed files`);
436
+ // In MODIFIED_CLASS mode, narrow to only Dtos with changed lines
437
+ if (mode === 'MODIFIED_CLASS') {
438
+ allDtos = filterTouchedDtos(allDtos, workspaceRoot, base, head);
439
+ if (allDtos.length === 0) {
440
+ console.log('✅ No Dto classes were modified');
441
+ return { success: true };
442
+ }
443
+ }
444
+ console.log(` Validating ${allDtos.length} Dto definition(s)`);
329
445
  const violations = findViolations(allDtos, dboModels);
330
446
  if (violations.length === 0) {
331
447
  console.log('✅ All Dto fields match their Dbo models');
@@ -365,6 +481,6 @@ async function runExecutor(options, context) {
365
481
  console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);
366
482
  console.log('');
367
483
  const changedFiles = getChangedFiles(workspaceRoot, base, head);
368
- return validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSourcePaths);
484
+ return validateDtoFiles(workspaceRoot, prismaSchemaPath, changedFiles, dtoSourcePaths, mode, base, head);
369
485
  }
370
486
  //# sourceMappingURL=executor.js.map