{"version":3,"file":"defaultStdioHarness.cjs","names":["path","fs"],"sources":["../../src/helpers/defaultStdioHarness.ts"],"sourcesContent":["import fs from 'node:fs/promises';\nimport path from 'node:path';\n\nexport const HARNESS_FILE_PRESETS = {\n  'judge.ts': 'stdioJudgePreset',\n  'debug.ts': 'stdioDebugPreset',\n} as const;\n\nexport type HarnessFileName = keyof typeof HARNESS_FILE_PRESETS;\n\n/**\n * Find harness files (`judge.ts` / `debug.ts`) in a problem directory whose content is identical to\n * the default stdio harness. Such files must not be committed: a problem without `judge.ts` is\n * judged with `stdioJudgePreset` (and debugged with `stdioDebugPreset`) automatically, and\n * committed copies would drift from the server's defaults.\n */\nexport async function findDefaultStdioHarnessFiles(problemDir: string): Promise<HarnessFileName[]> {\n  const judgeContent = await readFileOrUndefined(path.join(problemDir, 'judge.ts'));\n  const foundFileNames: HarnessFileName[] = [];\n  if (judgeContent !== undefined && isDefaultStdioHarnessSource(judgeContent, HARNESS_FILE_PRESETS['judge.ts'])) {\n    foundFileNames.push('judge.ts');\n  }\n  // A problem with a custom judge.ts gets no stdioDebugPreset fallback, so it must commit its own\n  // debug.ts — even one whose content matches the default stdio debug harness.\n  const hasCustomJudge = judgeContent !== undefined && foundFileNames.length === 0;\n  if (!hasCustomJudge) {\n    const debugContent = await readFileOrUndefined(path.join(problemDir, 'debug.ts'));\n    if (debugContent !== undefined && isDefaultStdioHarnessSource(debugContent, HARNESS_FILE_PRESETS['debug.ts'])) {\n      foundFileNames.push('debug.ts');\n    }\n  }\n  return foundFileNames;\n}\n\nasync function readFileOrUndefined(filePath: string): Promise<string | undefined> {\n  try {\n    return await fs.readFile(filePath, 'utf8');\n  } catch {\n    return undefined;\n  }\n}\n\n/**\n * Whether the source consists only of importing the given stdio preset from this package (or its\n * legacy `judge-utils` name) and awaiting it, i.e. it is semantically identical to the default\n * harness the server generates. Comments count as a difference on purpose: a harness kept for\n * demonstration can add an explanatory comment to be treated as custom.\n */\nexport function isDefaultStdioHarnessSource(source: string, presetName: string): boolean {\n  const importRegex = new RegExp(\n    String.raw`^\\s*import\\s*\\{\\s*${presetName}(?:\\s+as\\s+([A-Za-z_$][\\w$]*))?\\s*,?\\s*\\}\\s*from\\s*` +\n      String.raw`(['\"])(?:@exercode/problem-utils|judge-utils)/presets/stdio(?:\\.js)?\\2\\s*;?\\s*`\n  );\n  const importMatch = importRegex.exec(source);\n  if (!importMatch) return false;\n  const localPresetName = (importMatch[1] ?? presetName).replaceAll('$', String.raw`\\$`);\n  const callRegex = new RegExp(String.raw`^await\\s+${localPresetName}\\s*\\(\\s*import\\.meta\\.dirname\\s*\\)\\s*;?\\s*$`);\n  return callRegex.test(source.slice(importMatch[0].length));\n}\n"],"mappings":"iKAGA,MAAa,EAAuB,CAClC,WAAY,mBACZ,WAAY,kBACd,EAUA,eAAsB,EAA6B,EAAgD,CACjG,IAAM,EAAe,MAAM,EAAoBA,EAAAA,QAAK,KAAK,EAAY,UAAU,CAAC,EAC1E,EAAoC,CAAC,EAO3C,GANI,IAAiB,IAAA,IAAa,EAA4B,EAAc,EAAqB,WAAW,GAC1G,EAAe,KAAK,UAAU,EAIT,IAAiB,IAAA,IAAa,EAAe,SAAW,EAC1D,CACnB,IAAM,EAAe,MAAM,EAAoBA,EAAAA,QAAK,KAAK,EAAY,UAAU,CAAC,EAC5E,IAAiB,IAAA,IAAa,EAA4B,EAAc,EAAqB,WAAW,GAC1G,EAAe,KAAK,UAAU,CAElC,CACA,OAAO,CACT,CAEA,eAAe,EAAoB,EAA+C,CAChF,GAAI,CACF,OAAO,MAAMC,EAAAA,QAAG,SAAS,EAAU,MAAM,CAC3C,MAAQ,CACN,MACF,CACF,CAQA,SAAgB,EAA4B,EAAgB,EAA6B,CAKvF,IAAM,EAAc,IAJI,OACtB,OAAO,GAAG,qBAAqB,EAAW,qDACxC,OAAO,GAAG,gFAEgB,CAAC,CAAC,KAAK,CAAM,EAC3C,GAAI,CAAC,EAAa,MAAO,GACzB,IAAM,GAAmB,EAAY,IAAM,EAAA,CAAY,WAAW,IAAK,OAAO,GAAG,IAAI,EAErF,OAAO,IADe,OAAO,OAAO,GAAG,YAAY,EAAgB,4CACpD,CAAC,CAAC,KAAK,EAAO,MAAM,EAAY,EAAE,CAAC,MAAM,CAAC,CAC3D"}