{"version":3,"sources":["/Users/erunion/code/readme/oas/packages/jest-expect-jsonschema/dist/index.cjs","../src/index.ts"],"names":[],"mappings":"AAAA;ACOA,kGAAsB;AACtB,iGAAuB;AACvB,iFAAoB;AAgDpB,SAAS,eAAA,CAAgB,MAAA,EAAsB;AAC7C,EAAA,MAAM,WAAA,EAAsB;AAAA,IAC1B,MAAA,EAAQ,IAAA;AAAA,IACR,cAAA,EAAgB,IAAA;AAAA,IAChB,SAAA,EAAW;AAAA,EACb,CAAA;AAEA,EAAA,IAAI,GAAA;AACJ,EAAA,GAAA,CACE,UAAA,GAAa,OAAA,GACb,uBAAO,MAAA,2BAAQ,UAAA,IAAY,SAAA,mBAC3B,MAAA,6BAAQ,OAAA,qBAAQ,UAAA,mBAAW,uCAAuC,GAAA,EAClE;AACA,IAAA,IAAA,EAAM,IAAI,mBAAA,CAAQ,UAAU,CAAA;AAAA,EAC9B,EAAA,KAAO;AACL,IAAA,IAAA,EAAM,IAAI,yBAAA,CAAU,UAAU,CAAA;AAAA,EAChC;AAGA,EAAA,GAAA,CAAI,UAAA,CAAW;AAAA,IACb,OAAA,EAAS,mBAAA;AAAA,IACT,UAAA,EAAY;AAAA,EACd,CAAC,CAAA;AAID,EAAA,kCAAA,GAAc,CAAA;AAEd,EAAA,OAAO,GAAA;AACT;AAQA,MAAA,SAAsB,mBAAA,CAEpB,MAAA,EAIC;AACD,EAAA,MAAM,EAAE,WAAA,EAAa,aAAA,EAAe,cAAc,EAAA,EAAI,IAAA,CAAK,KAAA;AAE3D,EAAA,MAAM,IAAA,EAAM,eAAA,CAAgB,MAAM,CAAA;AAClC,EAAA,MAAM,MAAA,EAAQ,OAAA,CAAQ,MAAM,GAAA,CAAI,cAAA,CAAe,MAAM,CAAC,CAAA;AAEtD,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,KAAA;AAAA,IACN,OAAA,EAAS,CAAA,EAAA,GAAM;AACb,MAAA,OAAO,CAAA,EAAA;AAA2E;AAAO;AAAqB;AAAO;AACvH,IAAA;AACF,EAAA;AACF;AAQA;AAOU,EAAA;AAEG,EAAA;AACF,IAAA;AACC,MAAA;AACN,MAAA;AACyC;AAAA;AAAA;AAEpC;AACP,IAAA;AACF,EAAA;AAEM,EAAA;AACI,IAAA;AACA,MAAA;AACA,MAAA;AAEC,MAAA;AACR,IAAA;AACH,EAAA;AAEM,EAAA;AACA,EAAA;AAEC,EAAA;AACL,IAAA;AACS,IAAA;AACD,MAAA;AAAmF;AAAA;AACrF,MAAA;AACF,QAAA;AAAc;AAA+C;AAC/D,MAAA;AAEM,MAAA;AAC4B;AAAQ;AAAuB;AAAO;AAGjE,MAAA;AAAuE;AAAyB;AACzG,IAAA;AACF,EAAA;AACF;ADrFc;AACA;AACA;AACA","file":"/Users/erunion/code/readme/oas/packages/jest-expect-jsonschema/dist/index.cjs","sourcesContent":[null,"// Anchors the `@jest/expect` module augmentation below: since this file is a module, TS won't\n// resolve that augmentation unless something here actually pulls `@jest/expect` into the program.\n/// <reference types=\"@jest/expect\" />\n\nimport type { MatcherState } from '@vitest/expect';\nimport type { Options, SchemaObject } from 'ajv/dist/2020';\n\nimport AjvDraft4 from 'ajv-draft-04';\nimport addFormats from 'ajv-formats';\nimport Ajv2020 from 'ajv/dist/2020';\n\ndeclare global {\n  // oxlint-disable-next-line typescript/no-namespace -- This is how you type Jest matchers.\n  namespace jest {\n    interface Matchers<R> {\n      /**\n       * Assert that a given JSON Schema object is valid against the `$schema` version it\n       * identifies itself as.\n       *\n       * @param schema The JSON Schema object to validate.\n       */\n      toBeValidJSONSchema(): Promise<R>;\n\n      /**\n       * Assert that a given array of JSON Schema objects is valid against the `$schema` version\n       * that they each identify themselves as.\n       *\n       * @param schemas The array of JSON Schema objects to validate.\n       */\n      toBeValidJSONSchemas(): Promise<R>;\n    }\n  }\n}\n\n// This augments `@jest/expect`'s `Matchers` interface (as opposed to the ambient `jest` namespace\n// above) so that these matchers are typed when using `@jest/globals` instead of Jest's injected\n// globals.\ndeclare module '@jest/expect' {\n  interface Matchers<R> {\n    /**\n     * Assert that a given JSON Schema object is valid against the `$schema` version it\n     * identifies itself as.\n     *\n     * @param schema The JSON Schema object to validate.\n     */\n    toBeValidJSONSchema(): Promise<R>;\n\n    /**\n     * Assert that a given array of JSON Schema objects is valid against the `$schema` version\n     * that they each identify themselves as.\n     *\n     * @param schemas The array of JSON Schema objects to validate.\n     */\n    toBeValidJSONSchemas(): Promise<R>;\n  }\n}\n\nfunction getAJVForSchema(schema: SchemaObject) {\n  const ajvOptions: Options = {\n    strict: true,\n    validateSchema: true,\n    allErrors: true,\n  };\n\n  let ajv: Ajv2020 | AjvDraft4;\n  if (\n    '$schema' in schema &&\n    typeof schema?.$schema === 'string' &&\n    schema?.$schema.startsWith('https://json-schema.org/draft/2020-12')\n  ) {\n    ajv = new Ajv2020(ajvOptions);\n  } else {\n    ajv = new AjvDraft4(ajvOptions);\n  }\n\n  // `strict` mode flags `x-readme-ref-name` as an unknown keyword\n  ajv.addKeyword({\n    keyword: 'x-readme-ref-name',\n    schemaType: 'string',\n  });\n\n  // AJV by default doesn't understand formats like `int64`.\n  // @ts-expect-error -- `addFormats` is not typed correctly.\n  addFormats(ajv);\n\n  return ajv;\n}\n\n/**\n * Assert that a given JSON Schema object is valid against the `$schema` version it identifies\n * itself as.\n *\n * @param schema The JSON Schema object to validate.\n */\nexport async function toBeValidJSONSchema(\n  this: jest.MatcherUtils | MatcherState,\n  schema: Record<string, unknown>,\n): Promise<{\n  message: () => string;\n  pass: boolean;\n}> {\n  const { matcherHint, printExpected, printReceived } = this.utils;\n\n  const ajv = getAJVForSchema(schema);\n  const valid = Boolean(await ajv.validateSchema(schema));\n\n  return {\n    pass: valid,\n    message: () => {\n      return `${matcherHint(valid ? '.not.toBeValidJSONSchema' : '.toBeValidJSONSchema')}\\n\\n${printExpected(schema)}\\n\\n${printReceived(ajv.errors)}`;\n    },\n  };\n}\n\n/**\n * Assert that a given array of JSON Schema objects is valid against the `$schema` version that\n * they each identify themselves as.\n *\n * @param schemas The array of JSON Schema objects to validate.\n */\nexport async function toBeValidJSONSchemas(\n  this: jest.MatcherUtils | MatcherState,\n  schemas: SchemaObject[],\n): Promise<{\n  message: () => string;\n  pass: boolean;\n}> {\n  const { matcherHint, printExpected, printReceived } = this.utils;\n\n  if (!Array.isArray(schemas)) {\n    return {\n      pass: false,\n      message: () =>\n        `${matcherHint('.toBeValidJSONSchemas')}\\n\\n` +\n        'Expected an array of JSON Schema objects.\\n\\n' +\n        `${printReceived(schemas)}`,\n    };\n  }\n\n  const results = await Promise.all(\n    schemas.map(async (schema, i) => {\n      const ajv = getAJVForSchema(schema);\n      const valid = Boolean(await ajv.validateSchema(schema));\n\n      return valid ? null : { index: i, schema, errors: ajv.errors };\n    }),\n  );\n\n  const failures = results.filter((r): r is NonNullable<typeof r> => r !== null);\n  const pass = !failures.length;\n\n  return {\n    pass,\n    message: () => {\n      const hint = `${matcherHint(pass ? '.not.toBeValidJSONSchemas' : '.toBeValidJSONSchemas')}\\n\\n`;\n      if (pass) {\n        return `${hint}Expected array to have no valid schemas:\\n\\n${printExpected(schemas)}`;\n      }\n\n      const failureDetails = failures\n        .map(f => `Schema #${f.index + 1}:\\n\\n${printExpected(f.schema)}\\n\\n${printReceived(f.errors)}`)\n        .join('\\n\\n');\n\n      return `${hint}Expected all JSON Schema objects to be valid. ${failures.length} schema(s) failed:\\n\\n${failureDetails}`;\n    },\n  };\n}\n"]}