@webpieces/code-rules 0.3.139 → 0.3.141

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.
Files changed (52) hide show
  1. package/package.json +2 -2
  2. package/src/from-shared-config.js +20 -59
  3. package/src/from-shared-config.js.map +1 -1
  4. package/src/resolve-mode.d.ts +6 -0
  5. package/src/resolve-mode.js +40 -0
  6. package/src/resolve-mode.js.map +1 -0
  7. package/src/validate-catch-error-pattern.d.ts +1 -0
  8. package/src/validate-catch-error-pattern.js +7 -7
  9. package/src/validate-catch-error-pattern.js.map +1 -1
  10. package/src/validate-code-options.d.ts +13 -0
  11. package/src/validate-code-options.js.map +1 -1
  12. package/src/validate-code.js +49 -83
  13. package/src/validate-code.js.map +1 -1
  14. package/src/validate-dtos.d.ts +1 -0
  15. package/src/validate-dtos.js +7 -7
  16. package/src/validate-dtos.js.map +1 -1
  17. package/src/validate-modified-files.d.ts +2 -0
  18. package/src/validate-modified-files.js +6 -2
  19. package/src/validate-modified-files.js.map +1 -1
  20. package/src/validate-modified-methods.d.ts +2 -0
  21. package/src/validate-modified-methods.js +6 -2
  22. package/src/validate-modified-methods.js.map +1 -1
  23. package/src/validate-new-methods.d.ts +2 -0
  24. package/src/validate-new-methods.js +6 -2
  25. package/src/validate-new-methods.js.map +1 -1
  26. package/src/validate-no-any-unknown.d.ts +1 -0
  27. package/src/validate-no-any-unknown.js +7 -7
  28. package/src/validate-no-any-unknown.js.map +1 -1
  29. package/src/validate-no-destructure.d.ts +1 -0
  30. package/src/validate-no-destructure.js +7 -7
  31. package/src/validate-no-destructure.js.map +1 -1
  32. package/src/validate-no-direct-api-resolver.d.ts +1 -0
  33. package/src/validate-no-direct-api-resolver.js +7 -7
  34. package/src/validate-no-direct-api-resolver.js.map +1 -1
  35. package/src/validate-no-implicit-any.d.ts +1 -0
  36. package/src/validate-no-implicit-any.js +7 -7
  37. package/src/validate-no-implicit-any.js.map +1 -1
  38. package/src/validate-no-inline-types.d.ts +1 -0
  39. package/src/validate-no-inline-types.js +7 -7
  40. package/src/validate-no-inline-types.js.map +1 -1
  41. package/src/validate-no-symbol-di-tokens.d.ts +1 -0
  42. package/src/validate-no-symbol-di-tokens.js +7 -7
  43. package/src/validate-no-symbol-di-tokens.js.map +1 -1
  44. package/src/validate-no-unmanaged-exceptions.d.ts +1 -0
  45. package/src/validate-no-unmanaged-exceptions.js +7 -7
  46. package/src/validate-no-unmanaged-exceptions.js.map +1 -1
  47. package/src/validate-prisma-converters.d.ts +1 -0
  48. package/src/validate-prisma-converters.js +7 -7
  49. package/src/validate-prisma-converters.js.map +1 -1
  50. package/src/validate-return-types.d.ts +1 -0
  51. package/src/validate-return-types.js +7 -7
  52. package/src/validate-return-types.js.map +1 -1
@@ -53,6 +53,7 @@ const fs = tslib_1.__importStar(require("fs"));
53
53
  const path = tslib_1.__importStar(require("path"));
54
54
  const ts = tslib_1.__importStar(require("typescript"));
55
55
  const diff_utils_1 = require("./diff-utils");
56
+ const resolve_mode_1 = require("./resolve-mode");
56
57
  /**
57
58
  * Auto-detect the base branch by finding the merge-base with origin/main.
58
59
  */
@@ -595,21 +596,20 @@ function validateChangedFiles(workspaceRoot, schemaPath, convertersPaths, enforc
595
596
  * Resolve mode considering ignoreModifiedUntilEpoch override.
596
597
  * When active, downgrades to OFF. When expired, logs a warning.
597
598
  */
598
- function resolvePrismaConverterMode(normalMode, epoch) {
599
- if (epoch === undefined || normalMode === 'OFF') {
599
+ function resolvePrismaConverterMode(normalMode, epoch, branchPattern) {
600
+ if (normalMode === 'OFF') {
600
601
  return normalMode;
601
602
  }
602
- const nowSeconds = Date.now() / 1000;
603
- if (nowSeconds < epoch) {
604
- const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];
605
- console.log(`\n⏭️ Skipping prisma-converter validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);
603
+ const skip = (0, resolve_mode_1.shouldSkipRule)(epoch, branchPattern);
604
+ if (skip.skip) {
605
+ console.log(`\n⏭️ Skipping prisma-converter validation (${skip.reason})`);
606
606
  console.log('');
607
607
  return 'OFF';
608
608
  }
609
609
  return normalMode;
610
610
  }
611
611
  async function runValidator(options, workspaceRoot) {
612
- const mode = resolvePrismaConverterMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);
612
+ const mode = resolvePrismaConverterMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);
613
613
  if (mode === 'OFF') {
614
614
  console.log('\n⏭️ Skipping prisma-converter validation (mode: OFF)');
615
615
  console.log('');
@@ -1 +1 @@
1
- {"version":3,"file":"validate-prisma-converters.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-prisma-converters.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Prisma Converters Executor\n *\n * Validates that Prisma converter methods follow a scalable pattern:\n * methods returning XxxDto (where XxxDbo exists in schema.prisma) must\n * accept that exact XxxDbo as the first parameter. This keeps single-table\n * converters clean and forces join converters to compose them.\n *\n * ============================================================================\n * RULES\n * ============================================================================\n *\n * 1. First param must be exact Dbo:\n * If method returns XxxDto and XxxDbo exists in schema.prisma,\n * the first parameter must be of type XxxDbo.\n *\n * 2. Extra params must be booleans:\n * Additional parameters beyond the Dbo are allowed but must be boolean\n * (used for filtering payloads / security info).\n *\n * 3. No async converters:\n * Methods returning Promise<XxxDto> are flagged — converters should be\n * pure data mapping, no async work.\n *\n * 4. No standalone functions:\n * Standalone functions in converter files are flagged — must be class\n * methods so the converter class can be injected (dependency tree tracing).\n *\n * 5. Dto creation outside converters directory:\n * Files outside the configured convertersPath that create `new XxxDto(...)`\n * where XxxDbo exists in schema.prisma are flagged — Dto instances tied to\n * a Dbo must only be created via a converter class.\n *\n * ============================================================================\n * SKIP CONDITIONS\n * ============================================================================\n * - Methods with @deprecated decorator or JSDoc tag\n * - Lines with: // webpieces-disable prisma-converter -- [reason]\n *\n * ============================================================================\n * MODES\n * ============================================================================\n * - OFF: Skip validation entirely\n * - NEW_AND_MODIFIED_METHODS: Validate new/modified methods in converters + changed lines in non-converters\n * - MODIFIED_FILES: Validate all methods in modified files\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { getFileDiff, getChangedLineNumbers, findNewMethodSignaturesInDiff, isNewOrModified } from './diff-utils';\n\nexport type PrismaConverterMode = 'OFF' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\n\nexport interface ValidatePrismaConvertersOptions {\n mode?: PrismaConverterMode;\n disableAllowed?: boolean;\n schemaPath?: string;\n convertersPaths?: string[];\n enforcePaths?: string[];\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface PrismaConverterViolation {\n file: string;\n line: number;\n message: string;\n}\n\ninterface UnwrapResult {\n inner: string;\n isAsync: boolean;\n}\n\ninterface FileContext {\n filePath: string;\n fileLines: string[];\n sourceFile: ts.SourceFile;\n prismaModels: Set<string>;\n disableAllowed: boolean;\n}\n\n/**\n * Auto-detect the base branch by finding the merge-base with origin/main.\n */\nfunction detectBase(workspaceRoot: string): string | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD origin/main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err: unknown) {\n //const error = toError(err);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err2: unknown) {\n //const error2 = toError(err2);\n // Ignore\n }\n }\n return null;\n}\n\n/**\n * Get changed TypeScript files between base and head (or working tree if head not specified).\n */\n// webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths\nfunction getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n } catch (err: unknown) {\n //const error = toError(err);\n return changedFiles;\n }\n }\n\n return changedFiles;\n } catch (err: unknown) {\n //const error = toError(err);\n return [];\n }\n}\n\n/**\n * Parse schema.prisma to extract all model names into a Set.\n */\nfunction parsePrismaModels(schemaPath: string): Set<string> {\n const models = new Set<string>();\n\n if (!fs.existsSync(schemaPath)) {\n return models;\n }\n\n const content = fs.readFileSync(schemaPath, 'utf-8');\n const regex = /^model\\s+(\\w+)\\s*\\{/gm;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n models.add(match[1]);\n }\n\n return models;\n}\n\n/**\n * Derive the expected Dbo name from a return type ending in Dto.\n * \"XxxDto\" -> \"XxxDbo\". Returns null if name doesn't end with Dto.\n */\nfunction deriveExpectedDboName(returnType: string): string | null {\n if (!returnType.endsWith('Dto')) return null;\n return returnType.slice(0, -3) + 'Dbo';\n}\n\n/**\n * Check if a line has a webpieces-disable comment for prisma-converter.\n */\nfunction hasDisableComment(lines: string[], lineNumber: number): boolean {\n const startCheck = Math.max(0, lineNumber - 5);\n for (let i = lineNumber - 2; i >= startCheck; i--) {\n const line = lines[i]?.trim() ?? '';\n if (line.startsWith('function ') || line.startsWith('class ') || line.endsWith('}')) {\n break;\n }\n if (line.includes('webpieces-disable') && line.includes('prisma-converter')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a method/function node has a @deprecated decorator.\n */\nfunction hasDeprecatedDecorator(node: ts.MethodDeclaration | ts.FunctionDeclaration): boolean {\n const modifiers = ts.canHaveDecorators(node) ? ts.getDecorators(node) : undefined;\n if (!modifiers) return false;\n\n for (const decorator of modifiers) {\n const expr = decorator.expression;\n // @deprecated or @deprecated()\n if (ts.isIdentifier(expr) && expr.text === 'deprecated') return true;\n if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression) && expr.expression.text === 'deprecated') {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a node has @deprecated in its JSDoc comments.\n */\nfunction hasDeprecatedJsDoc(node: ts.Node): boolean {\n const jsDocs = ts.getJSDocTags(node);\n for (const tag of jsDocs) {\n if (tag.tagName.text === 'deprecated') return true;\n }\n return false;\n}\n\n/**\n * Check if a method is deprecated via decorator or JSDoc.\n */\nfunction isDeprecated(node: ts.MethodDeclaration | ts.FunctionDeclaration): boolean {\n return hasDeprecatedDecorator(node) || hasDeprecatedJsDoc(node);\n}\n\n/**\n * Extract the text of a type node, stripping whitespace.\n */\nfunction getTypeText(typeNode: ts.TypeNode, sourceFile: ts.SourceFile): string {\n return typeNode.getText(sourceFile).trim();\n}\n\n/**\n * Unwrap Promise<T> to get T. Returns the inner type text if wrapped, otherwise returns as-is.\n */\nfunction unwrapPromise(typeText: string): UnwrapResult {\n const promiseMatch = typeText.match(/^Promise\\s*<\\s*(.+)\\s*>$/);\n if (promiseMatch) {\n return { inner: promiseMatch[1].trim(), isAsync: true };\n }\n return { inner: typeText, isAsync: false };\n}\n\n/**\n * Check a standalone function declaration in a converter file and return a violation if applicable.\n */\nfunction checkStandaloneFunction(\n node: ts.FunctionDeclaration,\n ctx: FileContext\n): PrismaConverterViolation | null {\n if (!node.name) return null;\n\n const startPos = node.getStart(ctx.sourceFile);\n const pos = ctx.sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if ((ctx.disableAllowed && hasDisableComment(ctx.fileLines, line)) || isDeprecated(node)) return null;\n\n return {\n file: ctx.filePath,\n line,\n message: `Standalone function \"${node.name.text}\" found in converter file. ` +\n 'Move to a converter class so it can be injected via DI.',\n };\n}\n\n/**\n * Validate the parameters of a converter method that returns a Dto with a matching Dbo.\n */\nfunction checkMethodParams(\n node: ts.MethodDeclaration,\n innerType: string,\n expectedDbo: string,\n ctx: FileContext,\n line: number\n): PrismaConverterViolation[] {\n const violations: PrismaConverterViolation[] = [];\n const params = node.parameters;\n\n if (params.length === 0) {\n violations.push({\n file: ctx.filePath,\n line,\n message: `Method returns \"${innerType}\" but has no parameters. ` +\n `First parameter must be of type \"${expectedDbo}\".`,\n });\n return violations;\n }\n\n const firstParam = params[0];\n if (firstParam.type) {\n const firstParamType = getTypeText(firstParam.type, ctx.sourceFile);\n if (firstParamType !== expectedDbo) {\n violations.push({\n file: ctx.filePath,\n line,\n message: `Method returns \"${innerType}\" but first parameter is \"${firstParamType}\". ` +\n `First parameter must be of type \"${expectedDbo}\".`,\n });\n }\n }\n\n for (let i = 1; i < params.length; i++) {\n const param = params[i];\n if (param.type) {\n const paramType = getTypeText(param.type, ctx.sourceFile);\n if (paramType !== 'boolean') {\n const paramName = param.name.getText(ctx.sourceFile);\n violations.push({\n file: ctx.filePath,\n line,\n message: `Extra parameter \"${paramName}\" has type \"${paramType}\" but must be \"boolean\". ` +\n 'Additional converter parameters are only for boolean flags (payload filtering / security).',\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Check a class method declaration for converter pattern violations.\n */\nfunction checkConverterMethod(\n node: ts.MethodDeclaration,\n ctx: FileContext\n): PrismaConverterViolation[] {\n if (!node.name || !node.type) return [];\n\n const startPos = node.getStart(ctx.sourceFile);\n const pos = ctx.sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if ((ctx.disableAllowed && hasDisableComment(ctx.fileLines, line)) || isDeprecated(node)) return [];\n\n const returnTypeText = getTypeText(node.type, ctx.sourceFile);\n const unwrapResult = unwrapPromise(returnTypeText);\n const innerType = unwrapResult.inner;\n const isAsync = unwrapResult.isAsync;\n const expectedDbo = deriveExpectedDboName(innerType);\n\n if (!expectedDbo || !ctx.prismaModels.has(expectedDbo)) return [];\n\n if (isAsync) {\n return [{\n file: ctx.filePath,\n line,\n message: `Async converter method returning \"Promise<${innerType}>\" found. ` +\n 'Converters should be pure data mapping with no async work. Remove async/Promise.',\n }];\n }\n\n return checkMethodParams(node, innerType, expectedDbo, ctx, line);\n}\n\n/**\n * Find converter method violations in a single file.\n * Checks class methods for proper Dbo parameter patterns and flags standalone functions.\n */\nfunction findConverterViolationsInFile(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const ctx: FileContext = {\n filePath,\n fileLines: content.split('\\n'),\n sourceFile: ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true),\n prismaModels,\n disableAllowed,\n };\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node)) {\n const violation = checkStandaloneFunction(node, ctx);\n if (violation) violations.push(violation);\n }\n\n if (ts.isMethodDeclaration(node)) {\n violations.push(...checkConverterMethod(node, ctx));\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(ctx.sourceFile);\n return violations;\n}\n\n/**\n * Find violations in non-converter files: creating `new XxxDto(...)` where XxxDbo exists in prisma.\n * These Dto instances must only be created inside converter classes.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal for new-expression detection with prisma model matching\nfunction findDtoCreationOutsideConverters(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n convertersPaths: string[],\n disableAllowed: boolean\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n // Detect `new XxxDto(...)` expressions\n if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) {\n const className = node.expression.text;\n const expectedDbo = deriveExpectedDboName(className);\n\n if (expectedDbo && prismaModels.has(expectedDbo)) {\n const startPos = node.getStart(sourceFile);\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if (!disableAllowed || !hasDisableComment(fileLines, line)) {\n const dirs = convertersPaths.map((p) => `\"${p}\"`).join(', ');\n violations.push({\n file: filePath,\n line,\n message: `\"${className}\" can only be created from its Dbo using a converter in one of these directories: ${dirs}. ` +\n 'Move this Dto construction into a converter class method.',\n });\n }\n }\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(sourceFile);\n return violations;\n}\n\n/**\n * Find converter violations only for new/modified methods (NEW_AND_MODIFIED_METHODS mode).\n * For converter files: only check methods/functions that are new or have changed lines in their range.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal with method boundary filtering for new/modified detection\nfunction findConverterViolationsForModifiedMethods(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean,\n changedLines: Set<number>,\n newMethodNames: Set<string>\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const ctx: FileContext = {\n filePath,\n fileLines: content.split('\\n'),\n sourceFile: ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true),\n prismaModels,\n disableAllowed,\n };\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node) && node.name) {\n const start = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart(ctx.sourceFile));\n const end = ctx.sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n if (isNewOrModified(node.name.text, start.line + 1, end.line + 1, changedLines, newMethodNames)) {\n const violation = checkStandaloneFunction(node, ctx);\n if (violation) violations.push(violation);\n }\n }\n\n if (ts.isMethodDeclaration(node) && node.name) {\n const start = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart(ctx.sourceFile));\n const end = ctx.sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n const methodName = node.name.getText(ctx.sourceFile);\n if (isNewOrModified(methodName, start.line + 1, end.line + 1, changedLines, newMethodNames)) {\n violations.push(...checkConverterMethod(node, ctx));\n }\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(ctx.sourceFile);\n return violations;\n}\n\n/**\n * Find Dto creation violations only on changed lines (NEW_AND_MODIFIED_METHODS mode).\n * For non-converter files: only flag `new XxxDto(...)` on changed lines in the diff.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal for new-expression detection with changed-line filtering\nfunction findDtoCreationOnChangedLines(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n convertersPaths: string[],\n disableAllowed: boolean,\n changedLines: Set<number>\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) {\n const className = node.expression.text;\n const expectedDbo = deriveExpectedDboName(className);\n\n if (expectedDbo && prismaModels.has(expectedDbo)) {\n const startPos = node.getStart(sourceFile);\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if (changedLines.has(line) && (!disableAllowed || !hasDisableComment(fileLines, line))) {\n const dirs = convertersPaths.map((p) => `\"${p}\"`).join(', ');\n violations.push({\n file: filePath,\n line,\n message: `\"${className}\" can only be created from its Dbo using a converter in one of these directories: ${dirs}. ` +\n 'Move this Dto construction into a converter class method.',\n });\n }\n }\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(sourceFile);\n return violations;\n}\n\n/**\n * Collect violations for NEW_AND_MODIFIED_METHODS mode.\n * Converter files: method-level — only check new/modified methods.\n * Non-converter files: line-level — only flag new XxxDto() on changed lines.\n */\n// webpieces-disable max-lines-new-methods -- File classification and diff-based violation collection\nfunction collectViolationsForModifiedMethodAndCode(\n changedFiles: string[],\n convertersPaths: string[],\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean,\n base: string,\n head: string | undefined\n): PrismaConverterViolation[] {\n const converterFiles = changedFiles.filter((f) =>\n convertersPaths.some((cp) => f.startsWith(cp))\n );\n const nonConverterFiles = changedFiles.filter((f) =>\n !convertersPaths.some((cp) => f.startsWith(cp))\n );\n\n const allViolations: PrismaConverterViolation[] = [];\n\n if (converterFiles.length > 0) {\n console.log(`📂 Checking ${converterFiles.length} converter file(s) (new/modified methods only)...`);\n for (const file of converterFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n const newMethodNames = findNewMethodSignaturesInDiff(diff);\n if (changedLines.size === 0 && newMethodNames.size === 0) continue;\n allViolations.push(...findConverterViolationsForModifiedMethods(\n file, workspaceRoot, prismaModels, disableAllowed, changedLines, newMethodNames\n ));\n }\n }\n\n if (nonConverterFiles.length > 0) {\n console.log(`📂 Checking ${nonConverterFiles.length} non-converter file(s) for Dto creation (changed lines only)...`);\n for (const file of nonConverterFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n if (changedLines.size === 0) continue;\n allViolations.push(...findDtoCreationOnChangedLines(\n file, workspaceRoot, prismaModels, convertersPaths, disableAllowed, changedLines\n ));\n }\n }\n\n return allViolations;\n}\n\n/**\n * Report violations to console.\n */\nfunction reportViolations(violations: PrismaConverterViolation[], mode: PrismaConverterMode): void {\n console.error('');\n console.error('❌ Prisma converter violations found!');\n console.error('');\n console.error('📚 Converter methods returning XxxDto (where XxxDbo exists in schema.prisma)');\n console.error(' must accept XxxDbo as the first parameter. This keeps single-table');\n console.error(' converters clean and forces join converters to compose them.');\n console.error('');\n console.error(' GOOD: convertUserDbo(userDbo: UserDbo): UserDto { }');\n console.error(' GOOD: convertVersionDbo(version: VersionDbo, partial?: boolean): VersionDto { }');\n console.error(' GOOD: convertToJoinDto(item: SomeJoinType): CourseJoinDto { } // no matching JoinDbo');\n console.error('');\n console.error(' BAD: async convertUser(dbo: UserDbo): Promise<UserDto> { } // no async');\n console.error(' BAD: convertCourse(course: CourseWithMeta): CourseDto { } // wrong first param');\n console.error(' BAD: convertUser(dbo: UserDbo, name: string): UserDto { } // extra non-boolean');\n console.error(' BAD: export function convertSession(s: SessionDbo): SessionDto // standalone function');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}`);\n console.error(` ${v.message}`);\n }\n console.error('');\n\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable prisma-converter -- [your reason]');\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve git base ref from env vars or auto-detection.\n */\nfunction resolveBase(workspaceRoot: string): string | undefined {\n const envBase = process.env['NX_BASE'];\n if (envBase) return envBase;\n return detectBase(workspaceRoot) ?? undefined;\n}\n\n/**\n * Collect all violations from converter and non-converter files.\n */\nfunction collectAllViolations(\n changedFiles: string[],\n convertersPaths: string[],\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean\n): PrismaConverterViolation[] {\n const converterFiles = changedFiles.filter((f) =>\n convertersPaths.some((cp) => f.startsWith(cp))\n );\n const nonConverterFiles = changedFiles.filter((f) =>\n !convertersPaths.some((cp) => f.startsWith(cp))\n );\n\n const allViolations: PrismaConverterViolation[] = [];\n\n if (converterFiles.length > 0) {\n console.log(`📂 Checking ${converterFiles.length} converter file(s)...`);\n for (const file of converterFiles) {\n allViolations.push(...findConverterViolationsInFile(file, workspaceRoot, prismaModels, disableAllowed));\n }\n }\n\n if (nonConverterFiles.length > 0) {\n console.log(`📂 Checking ${nonConverterFiles.length} non-converter file(s) for Dto creation...`);\n for (const file of nonConverterFiles) {\n allViolations.push(...findDtoCreationOutsideConverters(file, workspaceRoot, prismaModels, convertersPaths, disableAllowed));\n }\n }\n\n return allViolations;\n}\n\n/**\n * Run validation after early-exit checks have passed.\n */\nfunction validateChangedFiles(\n workspaceRoot: string,\n schemaPath: string,\n convertersPaths: string[],\n enforcePaths: string[],\n base: string,\n mode: PrismaConverterMode,\n disableAllowed: boolean\n): ExecutorResult {\n const head = process.env['NX_HEAD'];\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const fullSchemaPath = path.join(workspaceRoot, schemaPath);\n const prismaModels = parsePrismaModels(fullSchemaPath);\n\n if (prismaModels.size === 0) {\n console.log('⏭️ No models found in schema.prisma');\n console.log('');\n return { success: true };\n }\n\n console.log(` Found ${prismaModels.size} model(s) in schema.prisma`);\n\n let changedFiles = getChangedTypeScriptFiles(workspaceRoot, base, head);\n if (enforcePaths.length > 0) {\n changedFiles = changedFiles.filter((f) =>\n enforcePaths.some((ep) => f.startsWith(ep))\n );\n }\n\n if (changedFiles.length === 0) {\n console.log('✅ No TypeScript files changed');\n return { success: true };\n }\n\n let allViolations: PrismaConverterViolation[];\n\n if (mode === 'NEW_AND_MODIFIED_METHODS') {\n allViolations = collectViolationsForModifiedMethodAndCode(\n changedFiles, convertersPaths, workspaceRoot, prismaModels, disableAllowed, base, head\n );\n } else {\n allViolations = collectAllViolations(changedFiles, convertersPaths, workspaceRoot, prismaModels, disableAllowed);\n }\n\n if (allViolations.length === 0) {\n console.log('✅ All converter patterns are valid');\n return { success: true };\n }\n\n reportViolations(allViolations, mode);\n return { success: false };\n}\n\n/**\n * Resolve mode considering ignoreModifiedUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolvePrismaConverterMode(\n normalMode: PrismaConverterMode,\n epoch: number | undefined\n): PrismaConverterMode {\n if (epoch === undefined || normalMode === 'OFF') {\n return normalMode;\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];\n console.log(`\\n⏭️ Skipping prisma-converter validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runValidator(\n options: ValidatePrismaConvertersOptions,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode = resolvePrismaConverterMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch);\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping prisma-converter validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n const schemaPath = options.schemaPath;\n const convertersPaths = options.convertersPaths ?? [];\n const enforcePaths = options.enforcePaths ?? [];\n\n if (!schemaPath || convertersPaths.length === 0) {\n const reason = !schemaPath ? 'no schemaPath configured' : 'no convertersPaths configured';\n console.log(`\\n⏭️ Skipping prisma-converter validation (${reason})`);\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating Prisma Converters\\n');\n console.log(` Mode: ${mode}`);\n console.log(` Schema: ${schemaPath}`);\n console.log(` Converter paths: ${convertersPaths.join(', ')}`);\n if (enforcePaths.length > 0) {\n console.log(` Enforce paths: ${enforcePaths.join(', ')}`);\n }\n\n const base = resolveBase(workspaceRoot);\n\n if (!base) {\n console.log('\\n⏭️ Skipping prisma-converter validation (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n\n const disableAllowed = options.disableAllowed ?? true;\n return validateChangedFiles(workspaceRoot, schemaPath, convertersPaths, enforcePaths, base, mode, disableAllowed);\n}\n"]}
1
+ {"version":3,"file":"validate-prisma-converters.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-prisma-converters.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Prisma Converters Executor\n *\n * Validates that Prisma converter methods follow a scalable pattern:\n * methods returning XxxDto (where XxxDbo exists in schema.prisma) must\n * accept that exact XxxDbo as the first parameter. This keeps single-table\n * converters clean and forces join converters to compose them.\n *\n * ============================================================================\n * RULES\n * ============================================================================\n *\n * 1. First param must be exact Dbo:\n * If method returns XxxDto and XxxDbo exists in schema.prisma,\n * the first parameter must be of type XxxDbo.\n *\n * 2. Extra params must be booleans:\n * Additional parameters beyond the Dbo are allowed but must be boolean\n * (used for filtering payloads / security info).\n *\n * 3. No async converters:\n * Methods returning Promise<XxxDto> are flagged — converters should be\n * pure data mapping, no async work.\n *\n * 4. No standalone functions:\n * Standalone functions in converter files are flagged — must be class\n * methods so the converter class can be injected (dependency tree tracing).\n *\n * 5. Dto creation outside converters directory:\n * Files outside the configured convertersPath that create `new XxxDto(...)`\n * where XxxDbo exists in schema.prisma are flagged — Dto instances tied to\n * a Dbo must only be created via a converter class.\n *\n * ============================================================================\n * SKIP CONDITIONS\n * ============================================================================\n * - Methods with @deprecated decorator or JSDoc tag\n * - Lines with: // webpieces-disable prisma-converter -- [reason]\n *\n * ============================================================================\n * MODES\n * ============================================================================\n * - OFF: Skip validation entirely\n * - NEW_AND_MODIFIED_METHODS: Validate new/modified methods in converters + changed lines in non-converters\n * - MODIFIED_FILES: Validate all methods in modified files\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { getFileDiff, getChangedLineNumbers, findNewMethodSignaturesInDiff, isNewOrModified } from './diff-utils';\nimport { shouldSkipRule } from './resolve-mode';\n\nexport type PrismaConverterMode = 'OFF' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\n\nexport interface ValidatePrismaConvertersOptions {\n mode?: PrismaConverterMode;\n disableAllowed?: boolean;\n schemaPath?: string;\n convertersPaths?: string[];\n enforcePaths?: string[];\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface PrismaConverterViolation {\n file: string;\n line: number;\n message: string;\n}\n\ninterface UnwrapResult {\n inner: string;\n isAsync: boolean;\n}\n\ninterface FileContext {\n filePath: string;\n fileLines: string[];\n sourceFile: ts.SourceFile;\n prismaModels: Set<string>;\n disableAllowed: boolean;\n}\n\n/**\n * Auto-detect the base branch by finding the merge-base with origin/main.\n */\nfunction detectBase(workspaceRoot: string): string | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD origin/main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err: unknown) {\n //const error = toError(err);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err2: unknown) {\n //const error2 = toError(err2);\n // Ignore\n }\n }\n return null;\n}\n\n/**\n * Get changed TypeScript files between base and head (or working tree if head not specified).\n */\n// webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths\nfunction getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n } catch (err: unknown) {\n //const error = toError(err);\n return changedFiles;\n }\n }\n\n return changedFiles;\n } catch (err: unknown) {\n //const error = toError(err);\n return [];\n }\n}\n\n/**\n * Parse schema.prisma to extract all model names into a Set.\n */\nfunction parsePrismaModels(schemaPath: string): Set<string> {\n const models = new Set<string>();\n\n if (!fs.existsSync(schemaPath)) {\n return models;\n }\n\n const content = fs.readFileSync(schemaPath, 'utf-8');\n const regex = /^model\\s+(\\w+)\\s*\\{/gm;\n let match: RegExpExecArray | null;\n\n while ((match = regex.exec(content)) !== null) {\n models.add(match[1]);\n }\n\n return models;\n}\n\n/**\n * Derive the expected Dbo name from a return type ending in Dto.\n * \"XxxDto\" -> \"XxxDbo\". Returns null if name doesn't end with Dto.\n */\nfunction deriveExpectedDboName(returnType: string): string | null {\n if (!returnType.endsWith('Dto')) return null;\n return returnType.slice(0, -3) + 'Dbo';\n}\n\n/**\n * Check if a line has a webpieces-disable comment for prisma-converter.\n */\nfunction hasDisableComment(lines: string[], lineNumber: number): boolean {\n const startCheck = Math.max(0, lineNumber - 5);\n for (let i = lineNumber - 2; i >= startCheck; i--) {\n const line = lines[i]?.trim() ?? '';\n if (line.startsWith('function ') || line.startsWith('class ') || line.endsWith('}')) {\n break;\n }\n if (line.includes('webpieces-disable') && line.includes('prisma-converter')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a method/function node has a @deprecated decorator.\n */\nfunction hasDeprecatedDecorator(node: ts.MethodDeclaration | ts.FunctionDeclaration): boolean {\n const modifiers = ts.canHaveDecorators(node) ? ts.getDecorators(node) : undefined;\n if (!modifiers) return false;\n\n for (const decorator of modifiers) {\n const expr = decorator.expression;\n // @deprecated or @deprecated()\n if (ts.isIdentifier(expr) && expr.text === 'deprecated') return true;\n if (ts.isCallExpression(expr) && ts.isIdentifier(expr.expression) && expr.expression.text === 'deprecated') {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a node has @deprecated in its JSDoc comments.\n */\nfunction hasDeprecatedJsDoc(node: ts.Node): boolean {\n const jsDocs = ts.getJSDocTags(node);\n for (const tag of jsDocs) {\n if (tag.tagName.text === 'deprecated') return true;\n }\n return false;\n}\n\n/**\n * Check if a method is deprecated via decorator or JSDoc.\n */\nfunction isDeprecated(node: ts.MethodDeclaration | ts.FunctionDeclaration): boolean {\n return hasDeprecatedDecorator(node) || hasDeprecatedJsDoc(node);\n}\n\n/**\n * Extract the text of a type node, stripping whitespace.\n */\nfunction getTypeText(typeNode: ts.TypeNode, sourceFile: ts.SourceFile): string {\n return typeNode.getText(sourceFile).trim();\n}\n\n/**\n * Unwrap Promise<T> to get T. Returns the inner type text if wrapped, otherwise returns as-is.\n */\nfunction unwrapPromise(typeText: string): UnwrapResult {\n const promiseMatch = typeText.match(/^Promise\\s*<\\s*(.+)\\s*>$/);\n if (promiseMatch) {\n return { inner: promiseMatch[1].trim(), isAsync: true };\n }\n return { inner: typeText, isAsync: false };\n}\n\n/**\n * Check a standalone function declaration in a converter file and return a violation if applicable.\n */\nfunction checkStandaloneFunction(\n node: ts.FunctionDeclaration,\n ctx: FileContext\n): PrismaConverterViolation | null {\n if (!node.name) return null;\n\n const startPos = node.getStart(ctx.sourceFile);\n const pos = ctx.sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if ((ctx.disableAllowed && hasDisableComment(ctx.fileLines, line)) || isDeprecated(node)) return null;\n\n return {\n file: ctx.filePath,\n line,\n message: `Standalone function \"${node.name.text}\" found in converter file. ` +\n 'Move to a converter class so it can be injected via DI.',\n };\n}\n\n/**\n * Validate the parameters of a converter method that returns a Dto with a matching Dbo.\n */\nfunction checkMethodParams(\n node: ts.MethodDeclaration,\n innerType: string,\n expectedDbo: string,\n ctx: FileContext,\n line: number\n): PrismaConverterViolation[] {\n const violations: PrismaConverterViolation[] = [];\n const params = node.parameters;\n\n if (params.length === 0) {\n violations.push({\n file: ctx.filePath,\n line,\n message: `Method returns \"${innerType}\" but has no parameters. ` +\n `First parameter must be of type \"${expectedDbo}\".`,\n });\n return violations;\n }\n\n const firstParam = params[0];\n if (firstParam.type) {\n const firstParamType = getTypeText(firstParam.type, ctx.sourceFile);\n if (firstParamType !== expectedDbo) {\n violations.push({\n file: ctx.filePath,\n line,\n message: `Method returns \"${innerType}\" but first parameter is \"${firstParamType}\". ` +\n `First parameter must be of type \"${expectedDbo}\".`,\n });\n }\n }\n\n for (let i = 1; i < params.length; i++) {\n const param = params[i];\n if (param.type) {\n const paramType = getTypeText(param.type, ctx.sourceFile);\n if (paramType !== 'boolean') {\n const paramName = param.name.getText(ctx.sourceFile);\n violations.push({\n file: ctx.filePath,\n line,\n message: `Extra parameter \"${paramName}\" has type \"${paramType}\" but must be \"boolean\". ` +\n 'Additional converter parameters are only for boolean flags (payload filtering / security).',\n });\n }\n }\n }\n\n return violations;\n}\n\n/**\n * Check a class method declaration for converter pattern violations.\n */\nfunction checkConverterMethod(\n node: ts.MethodDeclaration,\n ctx: FileContext\n): PrismaConverterViolation[] {\n if (!node.name || !node.type) return [];\n\n const startPos = node.getStart(ctx.sourceFile);\n const pos = ctx.sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if ((ctx.disableAllowed && hasDisableComment(ctx.fileLines, line)) || isDeprecated(node)) return [];\n\n const returnTypeText = getTypeText(node.type, ctx.sourceFile);\n const unwrapResult = unwrapPromise(returnTypeText);\n const innerType = unwrapResult.inner;\n const isAsync = unwrapResult.isAsync;\n const expectedDbo = deriveExpectedDboName(innerType);\n\n if (!expectedDbo || !ctx.prismaModels.has(expectedDbo)) return [];\n\n if (isAsync) {\n return [{\n file: ctx.filePath,\n line,\n message: `Async converter method returning \"Promise<${innerType}>\" found. ` +\n 'Converters should be pure data mapping with no async work. Remove async/Promise.',\n }];\n }\n\n return checkMethodParams(node, innerType, expectedDbo, ctx, line);\n}\n\n/**\n * Find converter method violations in a single file.\n * Checks class methods for proper Dbo parameter patterns and flags standalone functions.\n */\nfunction findConverterViolationsInFile(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const ctx: FileContext = {\n filePath,\n fileLines: content.split('\\n'),\n sourceFile: ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true),\n prismaModels,\n disableAllowed,\n };\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node)) {\n const violation = checkStandaloneFunction(node, ctx);\n if (violation) violations.push(violation);\n }\n\n if (ts.isMethodDeclaration(node)) {\n violations.push(...checkConverterMethod(node, ctx));\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(ctx.sourceFile);\n return violations;\n}\n\n/**\n * Find violations in non-converter files: creating `new XxxDto(...)` where XxxDbo exists in prisma.\n * These Dto instances must only be created inside converter classes.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal for new-expression detection with prisma model matching\nfunction findDtoCreationOutsideConverters(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n convertersPaths: string[],\n disableAllowed: boolean\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n // Detect `new XxxDto(...)` expressions\n if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) {\n const className = node.expression.text;\n const expectedDbo = deriveExpectedDboName(className);\n\n if (expectedDbo && prismaModels.has(expectedDbo)) {\n const startPos = node.getStart(sourceFile);\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if (!disableAllowed || !hasDisableComment(fileLines, line)) {\n const dirs = convertersPaths.map((p) => `\"${p}\"`).join(', ');\n violations.push({\n file: filePath,\n line,\n message: `\"${className}\" can only be created from its Dbo using a converter in one of these directories: ${dirs}. ` +\n 'Move this Dto construction into a converter class method.',\n });\n }\n }\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(sourceFile);\n return violations;\n}\n\n/**\n * Find converter violations only for new/modified methods (NEW_AND_MODIFIED_METHODS mode).\n * For converter files: only check methods/functions that are new or have changed lines in their range.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal with method boundary filtering for new/modified detection\nfunction findConverterViolationsForModifiedMethods(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean,\n changedLines: Set<number>,\n newMethodNames: Set<string>\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const ctx: FileContext = {\n filePath,\n fileLines: content.split('\\n'),\n sourceFile: ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true),\n prismaModels,\n disableAllowed,\n };\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n if (ts.isFunctionDeclaration(node) && node.name) {\n const start = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart(ctx.sourceFile));\n const end = ctx.sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n if (isNewOrModified(node.name.text, start.line + 1, end.line + 1, changedLines, newMethodNames)) {\n const violation = checkStandaloneFunction(node, ctx);\n if (violation) violations.push(violation);\n }\n }\n\n if (ts.isMethodDeclaration(node) && node.name) {\n const start = ctx.sourceFile.getLineAndCharacterOfPosition(node.getStart(ctx.sourceFile));\n const end = ctx.sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n const methodName = node.name.getText(ctx.sourceFile);\n if (isNewOrModified(methodName, start.line + 1, end.line + 1, changedLines, newMethodNames)) {\n violations.push(...checkConverterMethod(node, ctx));\n }\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(ctx.sourceFile);\n return violations;\n}\n\n/**\n * Find Dto creation violations only on changed lines (NEW_AND_MODIFIED_METHODS mode).\n * For non-converter files: only flag `new XxxDto(...)` on changed lines in the diff.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal for new-expression detection with changed-line filtering\nfunction findDtoCreationOnChangedLines(\n filePath: string,\n workspaceRoot: string,\n prismaModels: Set<string>,\n convertersPaths: string[],\n disableAllowed: boolean,\n changedLines: Set<number>\n): PrismaConverterViolation[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const violations: PrismaConverterViolation[] = [];\n\n function visitNode(node: ts.Node): void {\n if (ts.isNewExpression(node) && ts.isIdentifier(node.expression)) {\n const className = node.expression.text;\n const expectedDbo = deriveExpectedDboName(className);\n\n if (expectedDbo && prismaModels.has(expectedDbo)) {\n const startPos = node.getStart(sourceFile);\n const pos = sourceFile.getLineAndCharacterOfPosition(startPos);\n const line = pos.line + 1;\n\n if (changedLines.has(line) && (!disableAllowed || !hasDisableComment(fileLines, line))) {\n const dirs = convertersPaths.map((p) => `\"${p}\"`).join(', ');\n violations.push({\n file: filePath,\n line,\n message: `\"${className}\" can only be created from its Dbo using a converter in one of these directories: ${dirs}. ` +\n 'Move this Dto construction into a converter class method.',\n });\n }\n }\n }\n\n ts.forEachChild(node, visitNode);\n }\n\n visitNode(sourceFile);\n return violations;\n}\n\n/**\n * Collect violations for NEW_AND_MODIFIED_METHODS mode.\n * Converter files: method-level — only check new/modified methods.\n * Non-converter files: line-level — only flag new XxxDto() on changed lines.\n */\n// webpieces-disable max-lines-new-methods -- File classification and diff-based violation collection\nfunction collectViolationsForModifiedMethodAndCode(\n changedFiles: string[],\n convertersPaths: string[],\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean,\n base: string,\n head: string | undefined\n): PrismaConverterViolation[] {\n const converterFiles = changedFiles.filter((f) =>\n convertersPaths.some((cp) => f.startsWith(cp))\n );\n const nonConverterFiles = changedFiles.filter((f) =>\n !convertersPaths.some((cp) => f.startsWith(cp))\n );\n\n const allViolations: PrismaConverterViolation[] = [];\n\n if (converterFiles.length > 0) {\n console.log(`📂 Checking ${converterFiles.length} converter file(s) (new/modified methods only)...`);\n for (const file of converterFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n const newMethodNames = findNewMethodSignaturesInDiff(diff);\n if (changedLines.size === 0 && newMethodNames.size === 0) continue;\n allViolations.push(...findConverterViolationsForModifiedMethods(\n file, workspaceRoot, prismaModels, disableAllowed, changedLines, newMethodNames\n ));\n }\n }\n\n if (nonConverterFiles.length > 0) {\n console.log(`📂 Checking ${nonConverterFiles.length} non-converter file(s) for Dto creation (changed lines only)...`);\n for (const file of nonConverterFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const changedLines = getChangedLineNumbers(diff);\n if (changedLines.size === 0) continue;\n allViolations.push(...findDtoCreationOnChangedLines(\n file, workspaceRoot, prismaModels, convertersPaths, disableAllowed, changedLines\n ));\n }\n }\n\n return allViolations;\n}\n\n/**\n * Report violations to console.\n */\nfunction reportViolations(violations: PrismaConverterViolation[], mode: PrismaConverterMode): void {\n console.error('');\n console.error('❌ Prisma converter violations found!');\n console.error('');\n console.error('📚 Converter methods returning XxxDto (where XxxDbo exists in schema.prisma)');\n console.error(' must accept XxxDbo as the first parameter. This keeps single-table');\n console.error(' converters clean and forces join converters to compose them.');\n console.error('');\n console.error(' GOOD: convertUserDbo(userDbo: UserDbo): UserDto { }');\n console.error(' GOOD: convertVersionDbo(version: VersionDbo, partial?: boolean): VersionDto { }');\n console.error(' GOOD: convertToJoinDto(item: SomeJoinType): CourseJoinDto { } // no matching JoinDbo');\n console.error('');\n console.error(' BAD: async convertUser(dbo: UserDbo): Promise<UserDto> { } // no async');\n console.error(' BAD: convertCourse(course: CourseWithMeta): CourseDto { } // wrong first param');\n console.error(' BAD: convertUser(dbo: UserDbo, name: string): UserDto { } // extra non-boolean');\n console.error(' BAD: export function convertSession(s: SessionDbo): SessionDto // standalone function');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}`);\n console.error(` ${v.message}`);\n }\n console.error('');\n\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable prisma-converter -- [your reason]');\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve git base ref from env vars or auto-detection.\n */\nfunction resolveBase(workspaceRoot: string): string | undefined {\n const envBase = process.env['NX_BASE'];\n if (envBase) return envBase;\n return detectBase(workspaceRoot) ?? undefined;\n}\n\n/**\n * Collect all violations from converter and non-converter files.\n */\nfunction collectAllViolations(\n changedFiles: string[],\n convertersPaths: string[],\n workspaceRoot: string,\n prismaModels: Set<string>,\n disableAllowed: boolean\n): PrismaConverterViolation[] {\n const converterFiles = changedFiles.filter((f) =>\n convertersPaths.some((cp) => f.startsWith(cp))\n );\n const nonConverterFiles = changedFiles.filter((f) =>\n !convertersPaths.some((cp) => f.startsWith(cp))\n );\n\n const allViolations: PrismaConverterViolation[] = [];\n\n if (converterFiles.length > 0) {\n console.log(`📂 Checking ${converterFiles.length} converter file(s)...`);\n for (const file of converterFiles) {\n allViolations.push(...findConverterViolationsInFile(file, workspaceRoot, prismaModels, disableAllowed));\n }\n }\n\n if (nonConverterFiles.length > 0) {\n console.log(`📂 Checking ${nonConverterFiles.length} non-converter file(s) for Dto creation...`);\n for (const file of nonConverterFiles) {\n allViolations.push(...findDtoCreationOutsideConverters(file, workspaceRoot, prismaModels, convertersPaths, disableAllowed));\n }\n }\n\n return allViolations;\n}\n\n/**\n * Run validation after early-exit checks have passed.\n */\nfunction validateChangedFiles(\n workspaceRoot: string,\n schemaPath: string,\n convertersPaths: string[],\n enforcePaths: string[],\n base: string,\n mode: PrismaConverterMode,\n disableAllowed: boolean\n): ExecutorResult {\n const head = process.env['NX_HEAD'];\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const fullSchemaPath = path.join(workspaceRoot, schemaPath);\n const prismaModels = parsePrismaModels(fullSchemaPath);\n\n if (prismaModels.size === 0) {\n console.log('⏭️ No models found in schema.prisma');\n console.log('');\n return { success: true };\n }\n\n console.log(` Found ${prismaModels.size} model(s) in schema.prisma`);\n\n let changedFiles = getChangedTypeScriptFiles(workspaceRoot, base, head);\n if (enforcePaths.length > 0) {\n changedFiles = changedFiles.filter((f) =>\n enforcePaths.some((ep) => f.startsWith(ep))\n );\n }\n\n if (changedFiles.length === 0) {\n console.log('✅ No TypeScript files changed');\n return { success: true };\n }\n\n let allViolations: PrismaConverterViolation[];\n\n if (mode === 'NEW_AND_MODIFIED_METHODS') {\n allViolations = collectViolationsForModifiedMethodAndCode(\n changedFiles, convertersPaths, workspaceRoot, prismaModels, disableAllowed, base, head\n );\n } else {\n allViolations = collectAllViolations(changedFiles, convertersPaths, workspaceRoot, prismaModels, disableAllowed);\n }\n\n if (allViolations.length === 0) {\n console.log('✅ All converter patterns are valid');\n return { success: true };\n }\n\n reportViolations(allViolations, mode);\n return { success: false };\n}\n\n/**\n * Resolve mode considering ignoreModifiedUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolvePrismaConverterMode(\n normalMode: PrismaConverterMode,\n epoch: number | undefined,\n branchPattern: string | undefined\n): PrismaConverterMode {\n if (normalMode === 'OFF') {\n return normalMode;\n }\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n⏭️ Skipping prisma-converter validation (${skip.reason})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runValidator(\n options: ValidatePrismaConvertersOptions,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode = resolvePrismaConverterMode(options.mode ?? 'OFF', options.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping prisma-converter validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n const schemaPath = options.schemaPath;\n const convertersPaths = options.convertersPaths ?? [];\n const enforcePaths = options.enforcePaths ?? [];\n\n if (!schemaPath || convertersPaths.length === 0) {\n const reason = !schemaPath ? 'no schemaPath configured' : 'no convertersPaths configured';\n console.log(`\\n⏭️ Skipping prisma-converter validation (${reason})`);\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating Prisma Converters\\n');\n console.log(` Mode: ${mode}`);\n console.log(` Schema: ${schemaPath}`);\n console.log(` Converter paths: ${convertersPaths.join(', ')}`);\n if (enforcePaths.length > 0) {\n console.log(` Enforce paths: ${enforcePaths.join(', ')}`);\n }\n\n const base = resolveBase(workspaceRoot);\n\n if (!base) {\n console.log('\\n⏭️ Skipping prisma-converter validation (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n\n const disableAllowed = options.disableAllowed ?? true;\n return validateChangedFiles(workspaceRoot, schemaPath, convertersPaths, enforcePaths, base, mode, disableAllowed);\n}\n"]}
@@ -21,6 +21,7 @@ export interface ValidateReturnTypesOptions {
21
21
  mode?: ReturnTypeMode;
22
22
  disableAllowed?: boolean;
23
23
  ignoreModifiedUntilEpoch?: number;
24
+ ignoreRuleWhileOnBranch?: string;
24
25
  }
25
26
  export interface ExecutorResult {
26
27
  success: boolean;
@@ -24,6 +24,7 @@ const child_process_1 = require("child_process");
24
24
  const fs = tslib_1.__importStar(require("fs"));
25
25
  const path = tslib_1.__importStar(require("path"));
26
26
  const ts = tslib_1.__importStar(require("typescript"));
27
+ const resolve_mode_1 = require("./resolve-mode");
27
28
  /**
28
29
  * Get changed TypeScript files between base and head (or working tree if head not specified).
29
30
  */
@@ -386,21 +387,20 @@ function reportViolations(violations, mode) {
386
387
  * Resolve mode considering ignoreModifiedUntilEpoch override.
387
388
  * When active, downgrades to OFF. When expired, logs a warning.
388
389
  */
389
- function resolveMode(normalMode, epoch) {
390
- if (epoch === undefined || normalMode === 'OFF') {
390
+ function resolveMode(normalMode, epoch, branchPattern) {
391
+ if (normalMode === 'OFF') {
391
392
  return normalMode;
392
393
  }
393
- const nowSeconds = Date.now() / 1000;
394
- if (nowSeconds < epoch) {
395
- const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];
396
- console.log(`\n⏭️ Skipping require-return-type validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);
394
+ const skip = (0, resolve_mode_1.shouldSkipRule)(epoch, branchPattern);
395
+ if (skip.skip) {
396
+ console.log(`\n⏭️ Skipping require-return-type validation (${skip.reason})`);
397
397
  console.log('');
398
398
  return 'OFF';
399
399
  }
400
400
  return normalMode;
401
401
  }
402
402
  async function runValidator(options, workspaceRoot) {
403
- const mode = resolveMode(options.mode ?? 'NEW_METHODS', options.ignoreModifiedUntilEpoch);
403
+ const mode = resolveMode(options.mode ?? 'NEW_METHODS', options.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);
404
404
  const disableAllowed = options.disableAllowed ?? true;
405
405
  if (mode === 'OFF') {
406
406
  console.log('\n⏭️ Skipping return type validation (mode: OFF)');
@@ -1 +1 @@
1
- {"version":3,"file":"validate-return-types.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-return-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Return Types Executor\n *\n * Validates that methods have explicit return type annotations for better code readability.\n * Instead of relying on TypeScript's type inference, explicit return types make code clearer:\n *\n * BAD: method() { return new MyClass(); }\n * GOOD: method(): MyClass { return new MyClass(); }\n * GOOD: async method(): Promise<MyType> { ... }\n *\n * Modes:\n * - OFF: Skip validation entirely\n * - NEW_METHODS: Only validate new methods (detected via git diff)\n * - NEW_AND_MODIFIED_METHODS: Validate new methods + methods with changes in their line range\n * - MODIFIED_FILES: Validate all methods in modified files\n *\n * Escape hatch: Add webpieces-disable require-return-type comment with justification\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\n\nexport type ReturnTypeMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\n\nexport interface ValidateReturnTypesOptions {\n mode?: ReturnTypeMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface MethodViolation {\n file: string;\n methodName: string;\n line: number;\n}\n\n/**\n * Get changed TypeScript files between base and head (or working tree if head not specified).\n */\n// webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths\nfunction getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n } catch (err: unknown) {\n //const error = toError(err);\n return changedFiles;\n }\n }\n\n return changedFiles;\n } catch (err: unknown) {\n //const error = toError(err);\n return [];\n }\n}\n\n/**\n * Get the diff content for a specific file.\n */\nfunction getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const diff = execSync(`git diff ${diffTarget} -- \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n\n if (!diff && !head) {\n const fullPath = path.join(workspaceRoot, file);\n if (fs.existsSync(fullPath)) {\n const isUntracked = execSync(`git ls-files --others --exclude-standard \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n }).trim();\n\n if (isUntracked) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n const lines = content.split('\\n');\n return lines.map((line) => `+${line}`).join('\\n');\n }\n }\n }\n\n return diff;\n } catch (err: unknown) {\n //const error = toError(err);\n return '';\n }\n}\n\n/**\n * Parse diff to find newly added method signatures.\n */\nfunction findNewMethodSignaturesInDiff(diffContent: string): Set<string> {\n const newMethods = new Set<string>();\n const lines = diffContent.split('\\n');\n\n const patterns = [\n /^\\+\\s*(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s*)?\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?function/,\n /^\\+\\s*(?:(?:public|private|protected)\\s+)?(?:static\\s+)?(?:async\\s+)?(\\w+)\\s*\\(/,\n ];\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n const methodName = match[1];\n if (methodName && !['if', 'for', 'while', 'switch', 'catch', 'constructor'].includes(methodName)) {\n newMethods.add(methodName);\n }\n break;\n }\n }\n }\n }\n\n return newMethods;\n}\n\n/**\n * Check if a line contains a webpieces-disable comment for return type.\n */\nfunction hasDisableComment(lines: string[], lineNumber: number): boolean {\n const startCheck = Math.max(0, lineNumber - 5);\n for (let i = lineNumber - 2; i >= startCheck; i--) {\n const line = lines[i]?.trim() ?? '';\n if (line.startsWith('function ') || line.startsWith('class ') || line.endsWith('}')) {\n break;\n }\n if (line.includes('webpieces-disable') && line.includes('require-return-type')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a method has an explicit return type annotation.\n */\nfunction hasExplicitReturnType(node: ts.MethodDeclaration | ts.FunctionDeclaration | ts.ArrowFunction): boolean {\n return node.type !== undefined;\n}\n\ninterface MethodInfo {\n name: string;\n line: number;\n endLine: number;\n hasReturnType: boolean;\n hasDisableComment: boolean;\n}\n\n/**\n * Parse a TypeScript file and find methods with their return type status.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal requires inline visitor function\nfunction findMethodsInFile(filePath: string, workspaceRoot: string): MethodInfo[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const methods: MethodInfo[] = [];\n\n // webpieces-disable max-lines-new-methods -- AST visitor pattern requires handling multiple node types\n function visit(node: ts.Node): void {\n let methodName: string | undefined;\n let startLine: number | undefined;\n let endLine: number | undefined;\n let hasReturnType = false;\n\n if (ts.isMethodDeclaration(node) && node.name) {\n methodName = node.name.getText(sourceFile);\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n startLine = start.line + 1;\n endLine = end.line + 1;\n hasReturnType = hasExplicitReturnType(node);\n } else if (ts.isFunctionDeclaration(node) && node.name) {\n methodName = node.name.getText(sourceFile);\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n startLine = start.line + 1;\n endLine = end.line + 1;\n hasReturnType = hasExplicitReturnType(node);\n } else if (ts.isArrowFunction(node)) {\n if (ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {\n methodName = node.parent.name.getText(sourceFile);\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n startLine = start.line + 1;\n endLine = end.line + 1;\n hasReturnType = hasExplicitReturnType(node);\n }\n }\n\n if (methodName && startLine !== undefined && endLine !== undefined) {\n methods.push({\n name: methodName,\n line: startLine,\n endLine,\n hasReturnType,\n hasDisableComment: hasDisableComment(fileLines, startLine),\n });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return methods;\n}\n\n/**\n * Parse diff to extract changed line numbers (both additions and modifications).\n */\nfunction getChangedLineNumbers(diffContent: string): Set<number> {\n const changedLines = new Set<number>();\n const lines = diffContent.split('\\n');\n let currentLine = 0;\n\n for (const line of lines) {\n const hunkMatch = line.match(/^@@ -\\d+(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n if (hunkMatch) {\n currentLine = parseInt(hunkMatch[1], 10);\n continue;\n }\n\n if (line.startsWith('+') && !line.startsWith('+++')) {\n changedLines.add(currentLine);\n currentLine++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n // Deletions don't increment line number\n } else {\n currentLine++;\n }\n }\n\n return changedLines;\n}\n\n/**\n * Check if a method has any changed lines within its range.\n */\nfunction methodHasChanges(method: MethodInfo, changedLines: Set<number>): boolean {\n for (let line = method.line; line <= method.endLine; line++) {\n if (changedLines.has(line)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Find NEW methods without explicit return types (NEW_METHODS mode).\n */\n// webpieces-disable max-lines-new-methods -- File iteration with diff parsing and method matching\nfunction findViolationsForNewMethods(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean\n): MethodViolation[] {\n const violations: MethodViolation[] = [];\n\n for (const file of changedFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const newMethodNames = findNewMethodSignaturesInDiff(diff);\n\n if (newMethodNames.size === 0) continue;\n\n const methods = findMethodsInFile(file, workspaceRoot);\n\n for (const method of methods) {\n if (!newMethodNames.has(method.name)) continue;\n if (method.hasReturnType) continue;\n if (disableAllowed && method.hasDisableComment) continue;\n\n violations.push({\n file,\n methodName: method.name,\n line: method.line,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Find NEW methods AND methods with changes (NEW_AND_MODIFIED_METHODS mode).\n */\n// webpieces-disable max-lines-new-methods -- Combines new method detection with change detection\nfunction findViolationsForModifiedAndNewMethods(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean\n): MethodViolation[] {\n const violations: MethodViolation[] = [];\n\n for (const file of changedFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const newMethodNames = findNewMethodSignaturesInDiff(diff);\n const changedLines = getChangedLineNumbers(diff);\n\n const methods = findMethodsInFile(file, workspaceRoot);\n\n for (const method of methods) {\n if (method.hasReturnType) continue;\n if (disableAllowed && method.hasDisableComment) continue;\n\n const isNewMethod = newMethodNames.has(method.name);\n const isModifiedMethod = methodHasChanges(method, changedLines);\n\n if (!isNewMethod && !isModifiedMethod) continue;\n\n violations.push({\n file,\n methodName: method.name,\n line: method.line,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Find all methods without explicit return types in modified files (MODIFIED_FILES mode).\n */\nfunction findViolationsForModifiedFiles(workspaceRoot: string, changedFiles: string[], disableAllowed: boolean): MethodViolation[] {\n const violations: MethodViolation[] = [];\n\n for (const file of changedFiles) {\n const methods = findMethodsInFile(file, workspaceRoot);\n\n for (const method of methods) {\n if (method.hasReturnType) continue;\n if (disableAllowed && method.hasDisableComment) continue;\n\n violations.push({\n file,\n methodName: method.name,\n line: method.line,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Auto-detect the base branch by finding the merge-base with origin/main.\n */\nfunction detectBase(workspaceRoot: string): string | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD origin/main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err: unknown) {\n //const error = toError(err);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err2: unknown) {\n //const error2 = toError(err2);\n // Ignore\n }\n }\n return null;\n}\n\n/**\n * Report violations to console.\n */\nfunction reportViolations(violations: MethodViolation[], mode: ReturnTypeMode): void {\n console.error('');\n console.error('❌ Methods missing explicit return types!');\n console.error('');\n console.error('📚 Explicit return types improve code readability:');\n console.error('');\n console.error(' BAD: method() { return new MyClass(); }');\n console.error(' GOOD: method(): MyClass { return new MyClass(); }');\n console.error(' GOOD: async method(): Promise<MyType> { ... }');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}`);\n console.error(` Method: ${v.methodName} - missing return type annotation`);\n }\n console.error('');\n\n console.error(' To fix: Add explicit return type after the parameter list');\n console.error('');\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable require-return-type -- [your reason]');\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve mode considering ignoreModifiedUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolveMode(normalMode: ReturnTypeMode, epoch: number | undefined): ReturnTypeMode {\n if (epoch === undefined || normalMode === 'OFF') {\n return normalMode;\n }\n const nowSeconds = Date.now() / 1000;\n if (nowSeconds < epoch) {\n const expiresDate = new Date(epoch * 1000).toISOString().split('T')[0];\n console.log(`\\n⏭️ Skipping require-return-type validation (ignoreModifiedUntilEpoch active, expires: ${expiresDate})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runValidator(\n options: ValidateReturnTypesOptions,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode: ReturnTypeMode = resolveMode(options.mode ?? 'NEW_METHODS', options.ignoreModifiedUntilEpoch);\n const disableAllowed = options.disableAllowed ?? true;\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping return type validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating Return Types\\n');\n console.log(` Mode: ${mode}`);\n\n let base = process.env['NX_BASE'];\n const head = process.env['NX_HEAD'];\n\n if (!base) {\n base = detectBase(workspaceRoot) ?? undefined;\n\n if (!base) {\n console.log('\\n⏭️ Skipping return type validation (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const changedFiles = getChangedTypeScriptFiles(workspaceRoot, base, head);\n\n if (changedFiles.length === 0) {\n console.log('✅ No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: MethodViolation[] = [];\n\n if (mode === 'NEW_METHODS') {\n violations = findViolationsForNewMethods(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === 'NEW_AND_MODIFIED_METHODS') {\n violations = findViolationsForModifiedAndNewMethods(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === 'MODIFIED_FILES') {\n violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed);\n }\n\n if (violations.length === 0) {\n console.log('✅ All methods have explicit return types');\n return { success: true };\n }\n\n reportViolations(violations, mode);\n\n return { success: false };\n}\n"]}
1
+ {"version":3,"file":"validate-return-types.js","sourceRoot":"","sources":["../../../../../packages/tooling/code-rules/src/validate-return-types.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Validate Return Types Executor\n *\n * Validates that methods have explicit return type annotations for better code readability.\n * Instead of relying on TypeScript's type inference, explicit return types make code clearer:\n *\n * BAD: method() { return new MyClass(); }\n * GOOD: method(): MyClass { return new MyClass(); }\n * GOOD: async method(): Promise<MyType> { ... }\n *\n * Modes:\n * - OFF: Skip validation entirely\n * - NEW_METHODS: Only validate new methods (detected via git diff)\n * - NEW_AND_MODIFIED_METHODS: Validate new methods + methods with changes in their line range\n * - MODIFIED_FILES: Validate all methods in modified files\n *\n * Escape hatch: Add webpieces-disable require-return-type comment with justification\n */\n\nimport { execSync } from 'child_process';\nimport * as fs from 'fs';\nimport * as path from 'path';\nimport * as ts from 'typescript';\nimport { shouldSkipRule } from './resolve-mode';\n\nexport type ReturnTypeMode = 'OFF' | 'NEW_METHODS' | 'NEW_AND_MODIFIED_METHODS' | 'MODIFIED_FILES';\n\nexport interface ValidateReturnTypesOptions {\n mode?: ReturnTypeMode;\n disableAllowed?: boolean;\n ignoreModifiedUntilEpoch?: number;\n ignoreRuleWhileOnBranch?: string;\n}\n\nexport interface ExecutorResult {\n success: boolean;\n}\n\ninterface MethodViolation {\n file: string;\n methodName: string;\n line: number;\n}\n\n/**\n * Get changed TypeScript files between base and head (or working tree if head not specified).\n */\n// webpieces-disable max-lines-new-methods -- Git command handling with untracked files requires multiple code paths\nfunction getChangedTypeScriptFiles(workspaceRoot: string, base: string, head?: string): string[] {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const output = execSync(`git diff --name-only ${diffTarget} -- '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const changedFiles = output\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n\n if (!head) {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const untrackedOutput = execSync(`git ls-files --others --exclude-standard '*.ts' '*.tsx'`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n const untrackedFiles = untrackedOutput\n .trim()\n .split('\\n')\n .filter((f) => f && !f.includes('.spec.ts') && !f.includes('.test.ts'));\n const allFiles = new Set([...changedFiles, ...untrackedFiles]);\n return Array.from(allFiles);\n } catch (err: unknown) {\n //const error = toError(err);\n return changedFiles;\n }\n }\n\n return changedFiles;\n } catch (err: unknown) {\n //const error = toError(err);\n return [];\n }\n}\n\n/**\n * Get the diff content for a specific file.\n */\nfunction getFileDiff(workspaceRoot: string, file: string, base: string, head?: string): string {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const diffTarget = head ? `${base} ${head}` : base;\n const diff = execSync(`git diff ${diffTarget} -- \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n });\n\n if (!diff && !head) {\n const fullPath = path.join(workspaceRoot, file);\n if (fs.existsSync(fullPath)) {\n const isUntracked = execSync(`git ls-files --others --exclude-standard \"${file}\"`, {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n }).trim();\n\n if (isUntracked) {\n const content = fs.readFileSync(fullPath, 'utf-8');\n const lines = content.split('\\n');\n return lines.map((line) => `+${line}`).join('\\n');\n }\n }\n }\n\n return diff;\n } catch (err: unknown) {\n //const error = toError(err);\n return '';\n }\n}\n\n/**\n * Parse diff to find newly added method signatures.\n */\nfunction findNewMethodSignaturesInDiff(diffContent: string): Set<string> {\n const newMethods = new Set<string>();\n const lines = diffContent.split('\\n');\n\n const patterns = [\n /^\\+\\s*(?:export\\s+)?(?:async\\s+)?function\\s+(\\w+)\\s*\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s*)?\\(/,\n /^\\+\\s*(?:export\\s+)?(?:const|let)\\s+(\\w+)\\s*=\\s*(?:async\\s+)?function/,\n /^\\+\\s*(?:(?:public|private|protected)\\s+)?(?:static\\s+)?(?:async\\s+)?(\\w+)\\s*\\(/,\n ];\n\n for (const line of lines) {\n if (line.startsWith('+') && !line.startsWith('+++')) {\n for (const pattern of patterns) {\n const match = line.match(pattern);\n if (match) {\n const methodName = match[1];\n if (methodName && !['if', 'for', 'while', 'switch', 'catch', 'constructor'].includes(methodName)) {\n newMethods.add(methodName);\n }\n break;\n }\n }\n }\n }\n\n return newMethods;\n}\n\n/**\n * Check if a line contains a webpieces-disable comment for return type.\n */\nfunction hasDisableComment(lines: string[], lineNumber: number): boolean {\n const startCheck = Math.max(0, lineNumber - 5);\n for (let i = lineNumber - 2; i >= startCheck; i--) {\n const line = lines[i]?.trim() ?? '';\n if (line.startsWith('function ') || line.startsWith('class ') || line.endsWith('}')) {\n break;\n }\n if (line.includes('webpieces-disable') && line.includes('require-return-type')) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Check if a method has an explicit return type annotation.\n */\nfunction hasExplicitReturnType(node: ts.MethodDeclaration | ts.FunctionDeclaration | ts.ArrowFunction): boolean {\n return node.type !== undefined;\n}\n\ninterface MethodInfo {\n name: string;\n line: number;\n endLine: number;\n hasReturnType: boolean;\n hasDisableComment: boolean;\n}\n\n/**\n * Parse a TypeScript file and find methods with their return type status.\n */\n// webpieces-disable max-lines-new-methods -- AST traversal requires inline visitor function\nfunction findMethodsInFile(filePath: string, workspaceRoot: string): MethodInfo[] {\n const fullPath = path.join(workspaceRoot, filePath);\n if (!fs.existsSync(fullPath)) return [];\n\n const content = fs.readFileSync(fullPath, 'utf-8');\n const fileLines = content.split('\\n');\n const sourceFile = ts.createSourceFile(filePath, content, ts.ScriptTarget.Latest, true);\n\n const methods: MethodInfo[] = [];\n\n // webpieces-disable max-lines-new-methods -- AST visitor pattern requires handling multiple node types\n function visit(node: ts.Node): void {\n let methodName: string | undefined;\n let startLine: number | undefined;\n let endLine: number | undefined;\n let hasReturnType = false;\n\n if (ts.isMethodDeclaration(node) && node.name) {\n methodName = node.name.getText(sourceFile);\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n startLine = start.line + 1;\n endLine = end.line + 1;\n hasReturnType = hasExplicitReturnType(node);\n } else if (ts.isFunctionDeclaration(node) && node.name) {\n methodName = node.name.getText(sourceFile);\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n startLine = start.line + 1;\n endLine = end.line + 1;\n hasReturnType = hasExplicitReturnType(node);\n } else if (ts.isArrowFunction(node)) {\n if (ts.isVariableDeclaration(node.parent) && ts.isIdentifier(node.parent.name)) {\n methodName = node.parent.name.getText(sourceFile);\n const start = sourceFile.getLineAndCharacterOfPosition(node.getStart());\n const end = sourceFile.getLineAndCharacterOfPosition(node.getEnd());\n startLine = start.line + 1;\n endLine = end.line + 1;\n hasReturnType = hasExplicitReturnType(node);\n }\n }\n\n if (methodName && startLine !== undefined && endLine !== undefined) {\n methods.push({\n name: methodName,\n line: startLine,\n endLine,\n hasReturnType,\n hasDisableComment: hasDisableComment(fileLines, startLine),\n });\n }\n\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return methods;\n}\n\n/**\n * Parse diff to extract changed line numbers (both additions and modifications).\n */\nfunction getChangedLineNumbers(diffContent: string): Set<number> {\n const changedLines = new Set<number>();\n const lines = diffContent.split('\\n');\n let currentLine = 0;\n\n for (const line of lines) {\n const hunkMatch = line.match(/^@@ -\\d+(?:,\\d+)? \\+(\\d+)(?:,\\d+)? @@/);\n if (hunkMatch) {\n currentLine = parseInt(hunkMatch[1], 10);\n continue;\n }\n\n if (line.startsWith('+') && !line.startsWith('+++')) {\n changedLines.add(currentLine);\n currentLine++;\n } else if (line.startsWith('-') && !line.startsWith('---')) {\n // Deletions don't increment line number\n } else {\n currentLine++;\n }\n }\n\n return changedLines;\n}\n\n/**\n * Check if a method has any changed lines within its range.\n */\nfunction methodHasChanges(method: MethodInfo, changedLines: Set<number>): boolean {\n for (let line = method.line; line <= method.endLine; line++) {\n if (changedLines.has(line)) {\n return true;\n }\n }\n return false;\n}\n\n/**\n * Find NEW methods without explicit return types (NEW_METHODS mode).\n */\n// webpieces-disable max-lines-new-methods -- File iteration with diff parsing and method matching\nfunction findViolationsForNewMethods(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean\n): MethodViolation[] {\n const violations: MethodViolation[] = [];\n\n for (const file of changedFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const newMethodNames = findNewMethodSignaturesInDiff(diff);\n\n if (newMethodNames.size === 0) continue;\n\n const methods = findMethodsInFile(file, workspaceRoot);\n\n for (const method of methods) {\n if (!newMethodNames.has(method.name)) continue;\n if (method.hasReturnType) continue;\n if (disableAllowed && method.hasDisableComment) continue;\n\n violations.push({\n file,\n methodName: method.name,\n line: method.line,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Find NEW methods AND methods with changes (NEW_AND_MODIFIED_METHODS mode).\n */\n// webpieces-disable max-lines-new-methods -- Combines new method detection with change detection\nfunction findViolationsForModifiedAndNewMethods(\n workspaceRoot: string,\n changedFiles: string[],\n base: string,\n head: string | undefined,\n disableAllowed: boolean\n): MethodViolation[] {\n const violations: MethodViolation[] = [];\n\n for (const file of changedFiles) {\n const diff = getFileDiff(workspaceRoot, file, base, head);\n const newMethodNames = findNewMethodSignaturesInDiff(diff);\n const changedLines = getChangedLineNumbers(diff);\n\n const methods = findMethodsInFile(file, workspaceRoot);\n\n for (const method of methods) {\n if (method.hasReturnType) continue;\n if (disableAllowed && method.hasDisableComment) continue;\n\n const isNewMethod = newMethodNames.has(method.name);\n const isModifiedMethod = methodHasChanges(method, changedLines);\n\n if (!isNewMethod && !isModifiedMethod) continue;\n\n violations.push({\n file,\n methodName: method.name,\n line: method.line,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Find all methods without explicit return types in modified files (MODIFIED_FILES mode).\n */\nfunction findViolationsForModifiedFiles(workspaceRoot: string, changedFiles: string[], disableAllowed: boolean): MethodViolation[] {\n const violations: MethodViolation[] = [];\n\n for (const file of changedFiles) {\n const methods = findMethodsInFile(file, workspaceRoot);\n\n for (const method of methods) {\n if (method.hasReturnType) continue;\n if (disableAllowed && method.hasDisableComment) continue;\n\n violations.push({\n file,\n methodName: method.name,\n line: method.line,\n });\n }\n }\n\n return violations;\n}\n\n/**\n * Auto-detect the base branch by finding the merge-base with origin/main.\n */\nfunction detectBase(workspaceRoot: string): string | null {\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD origin/main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err: unknown) {\n //const error = toError(err);\n // eslint-disable-next-line @webpieces/no-unmanaged-exceptions\n try {\n const mergeBase = execSync('git merge-base HEAD main', {\n cwd: workspaceRoot,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n\n if (mergeBase) {\n return mergeBase;\n }\n } catch (err2: unknown) {\n //const error2 = toError(err2);\n // Ignore\n }\n }\n return null;\n}\n\n/**\n * Report violations to console.\n */\nfunction reportViolations(violations: MethodViolation[], mode: ReturnTypeMode): void {\n console.error('');\n console.error('❌ Methods missing explicit return types!');\n console.error('');\n console.error('📚 Explicit return types improve code readability:');\n console.error('');\n console.error(' BAD: method() { return new MyClass(); }');\n console.error(' GOOD: method(): MyClass { return new MyClass(); }');\n console.error(' GOOD: async method(): Promise<MyType> { ... }');\n console.error('');\n\n for (const v of violations) {\n console.error(` ❌ ${v.file}:${v.line}`);\n console.error(` Method: ${v.methodName} - missing return type annotation`);\n }\n console.error('');\n\n console.error(' To fix: Add explicit return type after the parameter list');\n console.error('');\n console.error(' Escape hatch (use sparingly):');\n console.error(' // webpieces-disable require-return-type -- [your reason]');\n console.error('');\n console.error(` Current mode: ${mode}`);\n console.error('');\n}\n\n/**\n * Resolve mode considering ignoreModifiedUntilEpoch override.\n * When active, downgrades to OFF. When expired, logs a warning.\n */\nfunction resolveMode(normalMode: ReturnTypeMode, epoch: number | undefined, branchPattern: string | undefined): ReturnTypeMode {\n if (normalMode === 'OFF') {\n return normalMode;\n }\n const skip = shouldSkipRule(epoch, branchPattern);\n if (skip.skip) {\n console.log(`\\n⏭️ Skipping require-return-type validation (${skip.reason})`);\n console.log('');\n return 'OFF';\n }\n return normalMode;\n}\n\nexport default async function runValidator(\n options: ValidateReturnTypesOptions,\n workspaceRoot: string\n): Promise<ExecutorResult> {\n const mode: ReturnTypeMode = resolveMode(options.mode ?? 'NEW_METHODS', options.ignoreModifiedUntilEpoch, options.ignoreRuleWhileOnBranch);\n const disableAllowed = options.disableAllowed ?? true;\n\n if (mode === 'OFF') {\n console.log('\\n⏭️ Skipping return type validation (mode: OFF)');\n console.log('');\n return { success: true };\n }\n\n console.log('\\n📏 Validating Return Types\\n');\n console.log(` Mode: ${mode}`);\n\n let base = process.env['NX_BASE'];\n const head = process.env['NX_HEAD'];\n\n if (!base) {\n base = detectBase(workspaceRoot) ?? undefined;\n\n if (!base) {\n console.log('\\n⏭️ Skipping return type validation (could not detect base branch)');\n console.log('');\n return { success: true };\n }\n }\n\n console.log(` Base: ${base}`);\n console.log(` Head: ${head ?? 'working tree (includes uncommitted changes)'}`);\n console.log('');\n\n const changedFiles = getChangedTypeScriptFiles(workspaceRoot, base, head);\n\n if (changedFiles.length === 0) {\n console.log('✅ No TypeScript files changed');\n return { success: true };\n }\n\n console.log(`📂 Checking ${changedFiles.length} changed file(s)...`);\n\n let violations: MethodViolation[] = [];\n\n if (mode === 'NEW_METHODS') {\n violations = findViolationsForNewMethods(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === 'NEW_AND_MODIFIED_METHODS') {\n violations = findViolationsForModifiedAndNewMethods(workspaceRoot, changedFiles, base, head, disableAllowed);\n } else if (mode === 'MODIFIED_FILES') {\n violations = findViolationsForModifiedFiles(workspaceRoot, changedFiles, disableAllowed);\n }\n\n if (violations.length === 0) {\n console.log('✅ All methods have explicit return types');\n return { success: true };\n }\n\n reportViolations(violations, mode);\n\n return { success: false };\n}\n"]}