{"version":3,"file":"index.mjs","names":["pkg.name"],"sources":["../src/utils/bundle.ts","../src/check/utils.ts","../src/check/index.ts","../src/test/schedule.ts","../src/test/utils.ts","../src/test/index.ts","../src/utils/config.ts","../src/cli.ts","../src/utils/tools.ts"],"sourcesContent":["import { existsSync } from 'node:fs'\nimport * as path from 'node:path'\n\nimport {\n  FsContentLoader,\n  FsContentWatcher,\n  type IContentLoader,\n  type IContentWatcher,\n  InterfaceBundle\n} from '@nekosu/maa-pipeline-manager'\n\nimport type { BaseConfig } from '../types/config'\n\nexport class CachedContentLoader implements IContentLoader {\n  private readonly loader: IContentLoader\n  private readonly contents = new Map<string, Promise<string | null>>()\n\n  constructor(loader: IContentLoader = new FsContentLoader()) {\n    this.loader = loader\n  }\n\n  get(file: string) {\n    let content = this.contents.get(file)\n    if (!content) {\n      content = this.loader.get(file)\n      this.contents.set(file, content)\n    }\n    return content\n  }\n}\n\nexport async function loadBundle(\n  cfg: BaseConfig,\n  loader: IContentLoader = new FsContentLoader(),\n  watcher: IContentWatcher = new FsContentWatcher()\n) {\n  const interfacePath = path.resolve(cfg.cwd ?? process.cwd(), cfg.interfacePath)\n\n  if (!existsSync(interfacePath)) {\n    console.log(`${interfacePath} not exists`)\n    return null\n  }\n\n  const bundle = new InterfaceBundle(\n    loader,\n    watcher,\n    false,\n    path.dirname(interfacePath),\n    path.basename(interfacePath),\n    cfg.parser\n  )\n  await bundle.load()\n  await bundle.flush(false) // 刷下 imports\n\n  return bundle\n}\n","export function calucateLocation(content: string, offset: number): [line: number, col: number] {\n  const previous = content.slice(0, offset)\n  let line = 0\n  let last = 0\n  for (let i = 0; i < previous.length; i++) {\n    if (previous[i] === '\\n') {\n      line += 1\n      last = i\n    }\n  }\n  return [line + 1, offset - last]\n}\n","import { error as coreError, warning as coreWarning, endGroup, startGroup } from '@actions/core'\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\n\nimport {\n  type Diagnostic,\n  FsContentWatcher,\n  type InterfaceBundle,\n  buildDiagnosticMessage,\n  joinPath,\n  performDiagnostic\n} from '@nekosu/maa-pipeline-manager'\n\nimport type { FullConfig } from '../types/config'\nimport { CachedContentLoader, loadBundle } from '../utils/bundle'\nimport { loadMaa, setupMaa } from '../utils/maa'\nimport { calucateLocation } from './utils'\n\ntype CheckTarget = {\n  controller: string\n  resource: string\n  labels: string[]\n}\n\ntype CheckResult = {\n  target: CheckTarget\n  diagnostics: Diagnostic[]\n  failedResourcePaths: string[]\n}\n\nfunction buildCheckTargets(bundle: InterfaceBundle) {\n  const targets = new Map<string, CheckTarget>()\n  for (const controller of bundle.allControllerNames()) {\n    for (const resource of bundle.allResourceNames(controller)) {\n      const paths = bundle.resolvePaths(controller, resource)\n      const key = JSON.stringify(paths)\n      const target = targets.get(key)\n      const label = `${controller} ${resource}`\n      if (target) {\n        target.labels.push(label)\n      } else {\n        targets.set(key, {\n          controller,\n          resource,\n          labels: [label]\n        })\n      }\n    }\n  }\n  return [...targets.values()]\n}\n\nfunction applyOverrides(cfg: FullConfig, diagnostics: Diagnostic[]) {\n  const result: Diagnostic[] = []\n  for (const diagnostic of diagnostics) {\n    const override = cfg.check?.override?.[diagnostic.type]\n    if (override === 'ignore') {\n      continue\n    }\n    if (override) {\n      result.push({\n        ...diagnostic,\n        level: override\n      })\n    } else {\n      result.push(diagnostic)\n    }\n  }\n  return result\n}\n\nasync function mapConcurrent<T, R>(\n  values: T[],\n  concurrency: number,\n  mapper: (value: T, index: number) => Promise<R>\n) {\n  const results = new Array<R>(values.length)\n  let nextIndex = 0\n  const workers = Array.from({ length: Math.min(concurrency, values.length) }, async () => {\n    while (nextIndex < values.length) {\n      const index = nextIndex\n      nextIndex += 1\n      results[index] = await mapper(values[index], index)\n    }\n  })\n  await Promise.all(workers)\n  return results\n}\n\nfunction resolveJobs(configuredJobs: number | undefined, targetCount: number) {\n  if (targetCount === 0) {\n    return 0\n  }\n\n  const defaultJobs = Math.min(4, os.availableParallelism())\n  const requestedJobs =\n    configuredJobs !== undefined && Number.isFinite(configuredJobs) && configuredJobs >= 1\n      ? Math.floor(configuredJobs)\n      : defaultJobs\n  return Math.min(targetCount, requestedJobs)\n}\n\nasync function checkTarget(\n  cfg: FullConfig,\n  target: CheckTarget,\n  loader: CachedContentLoader,\n  watcher: FsContentWatcher\n): Promise<CheckResult> {\n  const bundle = await loadBundle(cfg, loader, watcher)\n  if (!bundle) {\n    throw new Error('failed to reload interface bundle')\n  }\n\n  try {\n    await bundle.switchActive(target.controller, target.resource)\n    const diagnostics = applyOverrides(cfg, performDiagnostic(bundle, {}))\n    const failedResourcePaths: string[] = []\n    const resource = new maa.Resource()\n    try {\n      for (const folder of bundle.paths) {\n        const succeeded = await resource.post_bundle(joinPath(bundle.root, folder)).wait().succeeded\n        if (!succeeded) {\n          failedResourcePaths.push(folder)\n        }\n      }\n    } finally {\n      resource.destroy()\n    }\n\n    return {\n      target,\n      diagnostics,\n      failedResourcePaths\n    }\n  } finally {\n    bundle.stop()\n  }\n}\n\nexport async function runCheck(cfg: FullConfig): Promise<boolean> {\n  if (!cfg.check) {\n    return false\n  }\n\n  const modulePath = await setupMaa(cfg)\n  if (!modulePath) {\n    return false\n  }\n  await loadMaa(modulePath, path.resolve(cfg.cwd ?? process.cwd(), cfg.maaLogDir ?? 'debug'))\n  if (cfg.maaStdoutLevel) {\n    maa.Global.stdout_level = cfg.maaStdoutLevel\n  }\n\n  const repo = path.resolve(cfg.cwd ?? process.cwd(), cfg.repo ?? '.')\n\n  const result: Diagnostic[] = []\n\n  const loader = new CachedContentLoader()\n  const watcher = new FsContentWatcher()\n  const bundle = await loadBundle(cfg, loader, watcher)\n  if (!bundle) {\n    return false\n  }\n\n  const targets = buildCheckTargets(bundle)\n  const bundleRoot = bundle.root\n  bundle.stop()\n\n  const jobs = resolveJobs(cfg.check.job, targets.length)\n\n  if ((!cfg.mode || cfg.mode === 'stdio') && targets.length > 0) {\n    console.log(`checking ${targets.length} unique resource sets with ${jobs} jobs`)\n  }\n\n  const checkResults = await mapConcurrent(targets, jobs, target => {\n    return checkTarget(cfg, target, loader, watcher)\n  })\n\n  const files = new Map<string, Promise<string>>()\n  const locate = async (file: string, offset: number) => {\n    let content = files.get(file)\n    if (!content) {\n      content = fs.readFile(file, 'utf8')\n      files.set(file, content)\n    }\n    return calucateLocation(await content, offset)\n  }\n\n  let loadResourceFailed = false\n\n  for (const checkResult of checkResults) {\n    const label = checkResult.target.labels.join(', ')\n    if (!cfg.mode || cfg.mode === 'stdio') {\n      console.log(label)\n    } else if (cfg.mode === 'github') {\n      startGroup(label)\n    }\n\n    const formattedDiagnostics = await Promise.all(\n      checkResult.diagnostics.map(async diagnostic => {\n        const message = await buildDiagnosticMessage(bundleRoot, diagnostic, locate, {})\n        return [diagnostic, message] as const\n      })\n    )\n\n    for (const [diag, [start, _end, brief]] of formattedDiagnostics) {\n      const [line, col] = start\n      const relative = path.relative(repo, diag.file)\n      switch (cfg.mode ?? 'stdio') {\n        case 'stdio':\n          console.log(`  ${diag.level}: ${relative}:${line}:${col} ${brief}`)\n          break\n        case 'github':\n          switch (diag.level) {\n            case 'warning':\n              coreWarning(brief, {\n                file: relative,\n                startLine: line,\n                startColumn: col,\n                endColumn: col + diag.length\n              })\n              break\n            case 'error':\n              coreError(brief, {\n                file: relative,\n                startLine: line,\n                startColumn: col,\n                endColumn: col + diag.length\n              })\n              break\n          }\n      }\n    }\n\n    for (const failedPath of checkResult.failedResourcePaths) {\n      const message = `load resource failed: ${failedPath}`\n      if (!cfg.mode || cfg.mode === 'stdio') {\n        console.error(`  ${message}`)\n      } else if (cfg.mode === 'github') {\n        coreError(message)\n      }\n      loadResourceFailed = true\n    }\n\n    if (cfg.mode === 'github') {\n      endGroup()\n    }\n\n    result.push(...checkResult.diagnostics)\n  }\n\n  if (cfg.mode === 'json') {\n    process.stdout.write(JSON.stringify(result))\n    return true\n  }\n\n  const hasError = result.some(diag => diag.level === 'error')\n  return !hasError && !loadResourceFailed\n}\n","import type { TestCases } from '../types/config'\n\nexport type ResourcePlan = {\n  resourcePaths: readonly string[]\n}\n\nexport function getDefaultTestJobCount(cpuCount: number) {\n  return Math.max(1, Math.floor(cpuCount / 4))\n}\n\nexport function compareTestCases(left: TestCases, right: TestCases) {\n  const controllerOrder = left.configs.controller.localeCompare(right.configs.controller)\n  if (controllerOrder !== 0) {\n    return controllerOrder\n  }\n  return left.configs.resource.localeCompare(right.configs.resource)\n}\n\nexport function groupResourcePlans<T extends ResourcePlan>(plans: readonly T[]) {\n  const groups = new Map<string, T[]>()\n  for (const plan of plans) {\n    const key = JSON.stringify(plan.resourcePaths)\n    const group = groups.get(key)\n    if (group) {\n      group.push(plan)\n    } else {\n      groups.set(key, [plan])\n    }\n  }\n  return [...groups.values()]\n}\n","// return if real inside expect\nexport function checkRect(expect: maa.Rect, real: maa.Rect) {\n  return (\n    real[0] >= expect[0] &&\n    real[1] >= expect[1] &&\n    real[0] + real[2] <= expect[0] + expect[2] &&\n    real[1] + real[3] <= expect[1] + expect[3]\n  )\n}\n","import { info as coreInfo, warning as coreWarning } from '@actions/core'\nimport chalk from 'chalk'\nimport { existsSync } from 'node:fs'\nimport * as fs from 'node:fs/promises'\nimport * as os from 'node:os'\nimport * as path from 'node:path'\nimport * as workerpool from 'workerpool'\n\nimport { joinPath } from '@nekosu/maa-pipeline-manager'\n\nimport type { FullConfig } from '../types/config'\nimport { loadBundle } from '../utils/bundle'\nimport { setupMaa } from '../utils/maa'\nimport { compareTestCases, getDefaultTestJobCount, groupResourcePlans } from './schedule'\nimport type { GroupRecoResult, RecoJob, RecoResult } from './types'\nimport { checkRect } from './utils'\n\nfunction splitChunk<T>(arr: T[], size: number) {\n  const result: T[][] = []\n  let curr = 0\n  while (curr < arr.length) {\n    const next = curr + size\n    result.push(arr.slice(curr, next))\n    curr = next\n  }\n  return result\n}\n\ntype TestPlan = {\n  allImages: { image: string; imageRaw: string }[]\n  allNodes: string[]\n  resourcePaths: string[]\n  groupResult: GroupRecoResult\n}\n\nexport async function runTest(cfg: FullConfig) {\n  if (!cfg.test) {\n    return false\n  }\n\n  const modulePath = await setupMaa(cfg)\n  if (!modulePath) {\n    return false\n  }\n\n  const putLog = (log: string) => {\n    if (cfg.mode === 'github') {\n      coreInfo(log)\n    } else {\n      console.log(log)\n    }\n  }\n\n  const result: GroupRecoResult[] = []\n\n  const bundle = await loadBundle(cfg)\n  if (!bundle) {\n    return false\n  }\n\n  let finished = 0\n\n  let allTestCases = cfg.test.cases\n  if (typeof allTestCases === 'function') {\n    allTestCases = await allTestCases()\n  }\n\n  allTestCases = [...allTestCases].sort(compareTestCases)\n\n  const taskCount = allTestCases\n    .map(testCase => {\n      const imageCount = testCase.cases.length\n      const nodeCount = new Set(\n        testCase.cases\n          .map(c => c.hits.map(hit => (typeof hit === 'string' ? hit : hit.node)))\n          .flat()\n      ).size\n      return imageCount * nodeCount\n    })\n    .reduce((a, b) => a + b, 0)\n\n  const maxNodePerJob = cfg.test.maxNodePerJob ?? 50\n\n  const plans: TestPlan[] = []\n\n  try {\n    for (const testCases of allTestCases) {\n      const name =\n        testCases.configs.name ?? `${testCases.configs.controller}:${testCases.configs.resource}`\n\n      const allImages = testCases.cases\n        .map(c => ({\n          image: path.resolve(\n            cfg.cwd ?? process.cwd(),\n            cfg.test!.casesCwd ?? '.',\n            testCases.configs.imageRoot ?? '.',\n            c.image\n          ),\n          imageRaw: c.image\n        }))\n        .filter(({ image, imageRaw }) => {\n          if (!existsSync(image)) {\n            if (cfg.mode === 'github') {\n              coreWarning(`${name} ${imageRaw} not exists, ignored`)\n            } else {\n              console.log(`${name} ${imageRaw} not exists, ignored`)\n            }\n            return false\n          } else {\n            return true\n          }\n        })\n      const allNodes = [\n        ...new Set(\n          testCases.cases\n            .map(c => c.hits.map(hit => (typeof hit === 'string' ? hit : hit.node)).flat())\n            .flat()\n        )\n      ]\n\n      const resourcePaths = bundle\n        .resolvePaths(testCases.configs.controller, testCases.configs.resource)\n        .map(folder => joinPath(bundle.root, folder))\n      const groupResult: GroupRecoResult = {\n        cases: testCases,\n        result: []\n      }\n      result.push(groupResult)\n      plans.push({ allImages, allNodes, resourcePaths, groupResult })\n    }\n  } finally {\n    bundle.stop()\n  }\n\n  for (const [poolIndex, group] of groupResourcePlans(plans).entries()) {\n    const pool = workerpool.pool(path.join(import.meta.dirname, 'test', 'worker.mjs'), {\n      maxWorkers: cfg.test.job ?? getDefaultTestJobCount(os.cpus().length),\n      workerType: 'process',\n      forkOpts: {\n        env: {\n          MAAFW_MODULE_PATH: modulePath,\n          MAAFW_STDOUT_LEVEL: cfg.mode === 'json' ? 'Off' : cfg.maaStdoutLevel,\n          MAAFW_LOG_DIR: path.resolve(cfg.cwd ?? process.cwd(), cfg.maaLogDir ?? '.'),\n          MAAFW_RESOURCE_PATHS: group[0].resourcePaths.join(path.delimiter),\n          MAATOOLS_POOL_ID: String(poolIndex)\n        }\n      }\n    })\n\n    try {\n      for (const { allImages, allNodes, groupResult } of group) {\n        const tasks: Promise<void>[] = []\n        const scheduleJob = (job: RecoJob, result: RecoResult[]) => {\n          const task = pool\n            .exec<(job: RecoJob) => RecoResult[]>('performReco', [job])\n            .then(res => res)\n            .catch(err => {\n              console.log(err)\n              return []\n            })\n            .then(res => {\n              finished += res.length\n              result.push(...res)\n              process.stderr.write(\n                `${((finished * 100) / taskCount).toFixed(2)}% ${finished} / ${taskCount}\\r`\n              )\n            })\n          tasks.push(task)\n        }\n\n        for (const { image, imageRaw } of allImages) {\n          const nodesChunks = splitChunk(allNodes, maxNodePerJob)\n          for (const nodes of nodesChunks) {\n            scheduleJob(\n              {\n                nodes,\n                imagePath: image,\n                imagePathRaw: imageRaw\n              },\n              groupResult.result\n            )\n          }\n        }\n\n        await Promise.all(tasks)\n      }\n    } finally {\n      await pool.terminate()\n    }\n  }\n\n  let failed = false\n  const errorDetails: RecoResult[] = []\n  for (const group of result) {\n    const groupName =\n      group.cases.configs.name ??\n      `${group.cases.configs.controller}:${group.cases.configs.resource}`\n\n    let printed = false\n    const putError = (err: string) => {\n      if (!printed) {\n        putLog(chalk.red(groupName))\n        printed = true\n      }\n      putLog(err)\n      failed = true\n    }\n\n    for (const testCase of group.cases.cases) {\n      for (const res of group.result.filter(res => res.imagePathRaw === testCase.image)) {\n        const hitCfg = testCase.hits.find(hit => {\n          if (typeof hit === 'string') {\n            return hit === res.node\n          } else {\n            return hit.node === res.node\n          }\n        })\n\n        if (!res.detail) {\n          putError(`  ${testCase.image} ${res.node} missing detail.`)\n          errorDetails.push(res)\n          continue\n        }\n\n        if (hitCfg) {\n          if (!res.hit) {\n            putError(`  ${testCase.image} ${res.node} should hit but missed`)\n            errorDetails.push(res)\n          } else if (typeof hitCfg !== 'string') {\n            if (!res.detail.box || !checkRect(hitCfg.box, res.detail.box)) {\n              putError(\n                `  ${testCase.image} ${res.node} box mismatch. Expect ${JSON.stringify(hitCfg.box)}, hit ${JSON.stringify(res.detail.box)}`\n              )\n              errorDetails.push(res)\n            }\n          }\n        } else {\n          if (res.hit) {\n            putError(`  ${testCase.image} ${res.node} should missed but hit`)\n            errorDetails.push(res)\n          }\n        }\n      }\n    }\n\n    if (!printed) {\n      putLog(chalk.green(groupName))\n    }\n  }\n\n  if (errorDetails.length > 0) {\n    const file = path.resolve(\n      cfg.cwd ?? process.cwd(),\n      cfg.test.errorDetailsPath ?? 'maatoolsErrorDetails.json'\n    )\n    await fs.mkdir(path.dirname(file), { recursive: true })\n    await fs.writeFile(file, JSON.stringify(errorDetails, null, 2))\n  }\n\n  return !failed\n}\n","import { createJiti } from 'jiti'\nimport * as path from 'node:path'\n\nimport type { FullConfig } from '../types/config'\n\nexport async function loadConfig(file: string) {\n  try {\n    const jiti = createJiti(import.meta.url)\n    return (await jiti.import(path.resolve(process.cwd(), file), { default: true })) as FullConfig\n  } catch (_err) {\n    console.log(_err)\n    return null\n  }\n}\n","import { existsSync } from 'node:fs'\nimport * as fs from 'node:fs/promises'\n\nimport { setLocale } from '@nekosu/maa-locale'\n\nimport pkg from '../package.json'\nimport { runCheck } from './check'\nimport { runTest } from './test'\nimport type { FullConfig } from './types/config'\nimport { loadConfig } from './utils/config'\n\nconst defaultConfig = `import type { FullConfig } from '${pkg.name}'\n\nconst config: FullConfig = {\n  cwd: import.meta.dirname,\n  maaVersion: 'latest',\n  interfacePath: 'assets/interface.json',\n  check: {},\n}\n\nexport default config\n`\n\nexport async function runCli(cmd: string, cfg: string | FullConfig) {\n  if (cmd === 'init') {\n    if (!existsSync('maatools.config.mts')) {\n      await fs.writeFile('maatools.config.mts', defaultConfig)\n    } else {\n      console.error('maatools.config.mts exists')\n    }\n    return true\n  }\n\n  if (typeof cfg === 'string') {\n    const resolvedCfg = await loadConfig(cfg)\n    if (!resolvedCfg) {\n      console.error(`load ${cfg} failed`)\n      return false\n    }\n    cfg = resolvedCfg\n  }\n  if (process.env['GITHUB_ACTIONS']) {\n    if (!cfg.mode) {\n      cfg.mode = 'github'\n    }\n  }\n  if (cfg.locale) {\n    setLocale(cfg.locale)\n  }\n  switch (cmd) {\n    case 'check':\n      return await runCheck(cfg)\n\n    case 'test':\n      return await runTest(cfg)\n  }\n\n  console.log(`Usage: npx ${pkg.name} <init|check|test> [path to maatools.config.mts]`)\n\n  return false\n}\n","import { type ParseError, parse } from 'jsonc-parser'\nimport * as fs from 'node:fs/promises'\nimport * as path from 'node:path'\n\nimport type { TestCases } from '../types/config'\n\nexport async function loadTestCases(file: string) {\n  const content = await fs.readFile(file, 'utf8')\n  const errors: ParseError[] = []\n  const result = parse(content, errors) as TestCases\n  return errors.length > 0 ? null : result\n}\n\nexport async function loadAllTestCases(\n  folder: string,\n  pattern: string\n): Promise<[testCases: TestCases[], failFiles: string[]]> {\n  const results: TestCases[] = []\n  const fails: string[] = []\n  for await (const file of fs.glob(pattern, { cwd: folder })) {\n    const testCases = await loadTestCases(path.resolve(folder, file))\n    if (testCases) {\n      results.push(testCases)\n    } else {\n      fails.push(file)\n    }\n  }\n  return [results, fails]\n}\n"],"mappings":"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"}