{"version":3,"file":"validator.cjs","sourceRoot":"","sources":["../../src/manifest/validator.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAAyC;AAUzC,0EAAkD;AAQlD,MAAM,OAAO;IACX,OAAO,GAAsB,EAAE,CAAC;IAEvB,QAAQ,GAA4B,EAAE,CAAC;IAEhD,aAAa,GAAuB,SAAS,CAAC;IAE9C;;;;;OAKG;IACH,YAAY,OAAgC;QAC1C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED;;;;;;;OAOG;IACH,MAAM,CAAC,EAAU,EAAE,OAAe,EAAE,GAAkB;QACpD,IAAA,cAAM,EAAC,IAAI,CAAC,aAAa,KAAK,SAAS,CAAC,CAAC;QAEzC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,EAAE;YACF,OAAO;YACP,GAAG;YACH,QAAQ,EAAE,IAAI,CAAC,aAAa;SAC7B,CAAC,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,QAAyC;QAC3D,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,QAAQ,CAAC;IACzC,CAAC;IAED,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IACpE,CAAC;IAED,IAAI,OAAO;QACT,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;CACF;AAED;;;;;;;;;;GAUG;AACH,iEAAiE;AACjE,8DAA8D;AAC9D,+BAA+B;AACxB,KAAK,UAAU,aAAa,CACjC,KAA2B,EAC3B,QAAyB,MAAM,CAAC,MAAM,CAAC,iBAAiB,CAAC,EACzD,UAAmC,EAAE;IAErC,MAAM,OAAO,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAED,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC;QACtB,OAAO;YACL,OAAO,EAAE,OAAO,CAAC,OAAO;SACzB,CAAC;IACJ,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,mBAAmB,CAAC;YAC1B,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACxB,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,KAA4B,EAAE,OAAO,CAAC,CAAC;IACpE,CAAC;IAED,OAAO;QACL,KAAK,EAAE,KAA4B;QACnC,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC;AACJ,CAAC;AAjCD,sCAiCC;AAED;;;;;;GAMG;AACH,SAAgB,eAAe,CAAC,MAAuB,EAAE,UAAoB;IAC3E,OAAO,OAAO,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC;AAC7E,CAAC;AAFD,0CAEC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ,CACtB,OAAyB,EACzB,UAAoB;IAEpB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAC/E,CAAC;AALD,4BAKC","sourcesContent":["import { assert } from '@metamask/utils';\n\nimport type {\n  ValidatorContext,\n  ValidatorContextOptions,\n  ValidatorFix,\n  ValidatorMeta,\n  ValidatorReport,\n  ValidatorSeverity,\n} from './validator-types';\nimport * as defaultValidators from './validators';\nimport type { UnvalidatedSnapFiles, ExtendableSnapFiles } from '../types';\n\nexport type ValidatorResults = {\n  files?: ExtendableSnapFiles;\n  reports: ValidatorReport[];\n};\n\nclass Context implements ValidatorContext {\n  reports: ValidatorReport[] = [];\n\n  readonly #options: ValidatorContextOptions = {};\n\n  #nextSeverity?: ValidatorSeverity = undefined;\n\n  /**\n   * Construct a new validator context.\n   *\n   * @param options - The options for the validator context.\n   * @param options.exports - Exports detected by evaluating the bundle.\n   */\n  constructor(options: ValidatorContextOptions) {\n    this.#options = options;\n  }\n\n  /**\n   * Report a validation error or warning.\n   *\n   * @param id - The unique identifier for the report.\n   * @param message - The message describing the validation issue.\n   * @param fix - An optional fix function that can be used to automatically\n   * resolve the issue.\n   */\n  report(id: string, message: string, fix?: ValidatorFix): void {\n    assert(this.#nextSeverity !== undefined);\n\n    this.reports.push({\n      id,\n      message,\n      fix,\n      severity: this.#nextSeverity,\n    });\n  }\n\n  prepareForValidator(settings: { severity: ValidatorSeverity }) {\n    this.#nextSeverity = settings.severity;\n  }\n\n  get hasErrors() {\n    return this.reports.some((report) => report.severity === 'error');\n  }\n\n  get options() {\n    return this.#options;\n  }\n}\n\n/**\n * Verify that snap files are completely valid.\n * First it runs validators on unparsed files to check structure.\n * Secondly it runs validators on parsed files to check semantics.\n *\n * @param files - All files required to run a snap.\n * @param rules - Validators to run.\n * @param options - Options for the validation.\n * @param options.exports - Exports detected by evaluating the bundle.\n * @returns The validation results.\n */\n// TODO(ritave): snap.manifest.json and package.json should check\n//               json parsing as well instead of assuming it's\n//               already parsed\nexport async function runValidators(\n  files: UnvalidatedSnapFiles,\n  rules: ValidatorMeta[] = Object.values(defaultValidators),\n  options: ValidatorContextOptions = {},\n): Promise<ValidatorResults> {\n  const context = new Context(options);\n\n  for (const rule of rules) {\n    context.prepareForValidator({\n      severity: rule.severity,\n    });\n\n    await rule.structureCheck?.(files, context);\n  }\n\n  if (context.hasErrors) {\n    return {\n      reports: context.reports,\n    };\n  }\n\n  for (const rule of rules) {\n    context.prepareForValidator({\n      severity: rule.severity,\n    });\n\n    await rule.semanticCheck?.(files as ExtendableSnapFiles, context);\n  }\n\n  return {\n    files: files as ExtendableSnapFiles,\n    reports: context.reports,\n  };\n}\n\n/**\n * Check whether a report is fixable.\n *\n * @param report - The report to check.\n * @param errorsOnly - Whether to only consider errors for fixability.\n * @returns Whether the report is fixable.\n */\nexport function isReportFixable(report: ValidatorReport, errorsOnly?: boolean) {\n  return Boolean(report.fix && (!errorsOnly || report.severity === 'error'));\n}\n\n/**\n * Get whether any reports have pending fixes.\n *\n * @param results - Results of the validation run.\n * @param errorsOnly - Whether to only consider errors for pending fixes.\n * @returns Whether there are fixes pending.\n */\nexport function hasFixes(\n  results: ValidatorResults,\n  errorsOnly?: boolean,\n): boolean {\n  return results.reports.some((report) => isReportFixable(report, errorsOnly));\n}\n"]}