@atlassian/better-ajv-errors 3.0.0 → 3.0.1

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.
package/README.md CHANGED
@@ -14,9 +14,7 @@ Main goal of this library is to provide relevant error messages like the followi
14
14
  ## Installation
15
15
 
16
16
  ```bash
17
- $ npm i better-ajv-errors
18
- $ # Or
19
- $ yarn add better-ajv-errors
17
+ npm i better-ajv-errors
20
18
  ```
21
19
 
22
20
  Also install [ajv](https://www.npmjs.com/package/ajv), version 4.11.8 to 8, to validate data against JSON schemas. `better-ajv-errors` requires Node.js 22 or later.
package/dist/index.cjs CHANGED
@@ -26,7 +26,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  //#endregion
27
27
  let _humanwhocodes_momoa = require("@humanwhocodes/momoa");
28
28
  let node_util = require("node:util");
29
- let _babel_code_frame = require("@babel/code-frame");
30
29
  let leven = require("leven");
31
30
  leven = __toESM(leven, 1);
32
31
  let jsonpointer = require("jsonpointer");
@@ -48,6 +47,81 @@ const getChildren = (node) => node && getValues(node.children) || [];
48
47
  const getSiblings = (parent) => (node) => getChildren(parent).filter(not(eq(node)));
49
48
  const concatAll = (xs) => (ys) => ys.reduce((zs, z) => zs.concat(z), xs);
50
49
  //#endregion
50
+ //#region src/code-frame.js
51
+ const LINES_ABOVE = 2;
52
+ const LINES_BELOW = 3;
53
+ const NEWLINE = /\r\n|[\r\n]/;
54
+ const TOKEN_STYLES = {
55
+ String: "green",
56
+ Number: "magenta",
57
+ Boolean: "cyan",
58
+ Null: "cyan",
59
+ Colon: "yellow",
60
+ Comma: "yellow"
61
+ };
62
+ const MARKER_STYLE = ["red", "bold"];
63
+ const supportsColor = () => (0, node_util.styleText)("red", "-") !== "-";
64
+ /**
65
+ * Renders the lines of `source` around `location`, with carets under the located text and
66
+ * `message` after the last caret.
67
+ *
68
+ * Lines and columns are 1-based and `end` is exclusive, as in momoa's locations. Without
69
+ * `end`, a single caret marks `start`.
70
+ *
71
+ * @param {string} source
72
+ * @param {{ start: { line: number, column: number }, end?: { line: number, column: number } }} location
73
+ * @param {{ message?: string, color?: boolean }} [options]
74
+ * @return {string}
75
+ */
76
+ function codeFrame(source, { start, end = start }, { message, color = supportsColor() } = {}) {
77
+ const paint = color ? (format, text) => (0, node_util.styleText)(format, text, { validateStream: false }) : (_format, text) => text;
78
+ const lines = source.split(NEWLINE);
79
+ const markers = getMarkers(lines, start, end);
80
+ const first = Math.max(start.line - LINES_ABOVE, 1);
81
+ const last = Math.min(end.line + LINES_BELOW, lines.length);
82
+ const width = String(last).length;
83
+ const rows = [];
84
+ for (let number = first; number <= last; number++) {
85
+ const line = lines[number - 1];
86
+ const gutter = ` ${String(number).padStart(width)} |`;
87
+ const code = line.length > 0 ? ` ${color ? highlight(line, paint) : line}` : "";
88
+ const marker = markers.get(number);
89
+ if (!marker) {
90
+ rows.push(` ${paint("gray", gutter)}${code}`);
91
+ continue;
92
+ }
93
+ const [column, count] = marker;
94
+ const spacing = line.slice(0, column - 1).replace(/[^\t]/g, " ");
95
+ let caretRow = ` ${paint("gray", gutter.replace(/\d/g, " "))} ${spacing}${paint(MARKER_STYLE, "^".repeat(count))}`;
96
+ if (message && number === end.line) caretRow += ` ${paint(MARKER_STYLE, message)}`;
97
+ rows.push(`${paint(MARKER_STYLE, ">")}${paint("gray", gutter)}${code}`, caretRow);
98
+ }
99
+ return rows.join("\n");
100
+ }
101
+ function getMarkers(lines, start, end) {
102
+ const markers = /* @__PURE__ */ new Map();
103
+ if (start.line === end.line) {
104
+ markers.set(start.line, [start.column, Math.max(end.column - start.column, 1)]);
105
+ return markers;
106
+ }
107
+ markers.set(start.line, [start.column, lines[start.line - 1].length - start.column + 1]);
108
+ for (let number = start.line + 1; number < end.line; number++) markers.set(number, [1, Math.max(lines[number - 1].length, 1)]);
109
+ markers.set(end.line, [1, end.column - 1]);
110
+ return markers;
111
+ }
112
+ function highlight(line, paint) {
113
+ let output = "";
114
+ let offset = 0;
115
+ for (const { type, loc } of (0, _humanwhocodes_momoa.tokenize)(line)) {
116
+ const style = TOKEN_STYLES[type];
117
+ if (style) {
118
+ output += line.slice(offset, loc.start.offset) + paint(style, line.slice(loc.start.offset, loc.end.offset));
119
+ offset = loc.end.offset;
120
+ }
121
+ }
122
+ return output + line.slice(offset);
123
+ }
124
+ //#endregion
51
125
  //#region src/json/utils.js
52
126
  const getPointers = (dataPath) => {
53
127
  return dataPath.split("/").slice(1).map((pointer) => pointer.split("~1").join("/").split("~0").join("~"));
@@ -128,10 +202,7 @@ var BaseValidationError = class {
128
202
  return decoratedPath ? `${decoratedPath}${separator}${message}` : message;
129
203
  }
130
204
  getCodeFrame(message, dataPath = this.instancePath) {
131
- return (0, _babel_code_frame.codeFrameColumns)(this.jsonRaw, this.getLocation(dataPath), {
132
- highlightCode: true,
133
- message
134
- });
205
+ return codeFrame(this.jsonRaw, this.getLocation(dataPath), { message });
135
206
  }
136
207
  /**
137
208
  * @return {string}
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["codeFrameColumns","styleText","styleText","styleText","pointer","styleText","parse","prettify"],"sources":["../src/utils.js","../src/json/utils.js","../src/json/get-meta-from-path.js","../src/json/get-decorated-data-path.js","../src/validation-errors/base.js","../src/validation-errors/required.js","../src/validation-errors/additional-prop.js","../src/validation-errors/enum.js","../src/validation-errors/default.js","../src/helpers.js","../src/index.js"],"sourcesContent":["// Basic\nconst eq = x => y => x === y;\nconst not = fn => x => !fn(x);\n\nconst getValues = o => Object.values(o);\n\nexport const notUndefined = x => x !== undefined;\n\n// Error\nconst isXError = x => error => error.keyword === x;\nexport const isRequiredError = isXError('required');\nexport const isAnyOfError = isXError('anyOf');\nexport const isEnumError = isXError('enum');\nexport const getErrors = node =>\n node && node.errors\n ? node.errors.map(e =>\n e.keyword === 'errorMessage' ? { ...e.params.errors[0], message: e.message } : e\n )\n : [];\n\n// Node\nexport const getChildren = node => (node && getValues(node.children)) || [];\n\nexport const getSiblings = parent => node => getChildren(parent).filter(not(eq(node)));\n\nexport const concatAll = xs => ys => ys.reduce((zs, z) => zs.concat(z), xs);\n","// TODO: Better error handling\nexport const getPointers = dataPath => {\n return dataPath\n .split('/')\n .slice(1)\n .map(pointer => pointer.split('~1').join('/').split('~0').join('~'));\n};\n","import { getPointers } from './utils';\n\nexport default function getMetaFromPath(jsonAst, dataPath, includeIdentifierLocation) {\n const pointers = getPointers(dataPath);\n const lastPointerIndex = pointers.length - 1;\n return pointers.reduce((obj, pointer, idx) => {\n switch (obj.type) {\n case 'Object': {\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n\n const { name, value } = member;\n return includeIdentifierLocation && idx === lastPointerIndex ? name : value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n return element && element.value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n}\n","import { getPointers } from './utils';\n\nexport default function getDecoratedDataPath(jsonAst, dataPath) {\n let decoratedPath = '';\n getPointers(dataPath).reduce((obj, pointer) => {\n switch (obj.type) {\n case 'Object': {\n decoratedPath += `/${pointer}`;\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n return member.value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n const value = element && element.value;\n decoratedPath += `/${pointer}${getTypeName(value)}`;\n return value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n return decoratedPath;\n}\n\nfunction getTypeName(obj) {\n if (!obj || !obj.elements) {\n return '';\n }\n const type = obj.elements.filter(child => child && child.name && child.name.value === 'type');\n\n if (!type.length) {\n return '';\n }\n\n return (type[0].value && `:${type[0].value.value}`) || '';\n}\n","import { codeFrameColumns } from '@babel/code-frame';\nimport { getMetaFromPath, getDecoratedDataPath } from '../json/index';\n\nexport default class BaseValidationError {\n constructor(options = { isIdentifierLocation: false }, { data, schema, jsonAst, jsonRaw }) {\n this.options = options;\n this.data = data;\n this.schema = schema;\n this.jsonAst = jsonAst;\n this.jsonRaw = jsonRaw;\n }\n\n getLocation(dataPath = this.instancePath) {\n const { isIdentifierLocation, isSkipEndLocation } = this.options;\n const { loc } = getMetaFromPath(this.jsonAst, dataPath, isIdentifierLocation);\n return {\n start: loc.start,\n end: isSkipEndLocation ? undefined : loc.end,\n };\n }\n\n getDecoratedPath(dataPath = this.instancePath) {\n const decoratedPath = getDecoratedDataPath(this.jsonAst, dataPath);\n return decoratedPath;\n }\n\n // The decorated path is empty at the root, where the message stands alone.\n withDecoratedPath(message, separator = ' ') {\n const decoratedPath = this.getDecoratedPath();\n return decoratedPath ? `${decoratedPath}${separator}${message}` : message;\n }\n\n getCodeFrame(message, dataPath = this.instancePath) {\n return codeFrameColumns(this.jsonRaw, this.getLocation(dataPath), {\n highlightCode: true,\n message,\n });\n }\n\n /**\n * @return {string}\n */\n get instancePath() {\n return typeof this.options.instancePath !== 'undefined'\n ? this.options.instancePath\n : this.options.dataPath;\n }\n\n print() {\n throw new Error(`Implement the 'print' method inside ${this.constructor.name}!`);\n }\n\n getError() {\n throw new Error(`Implement the 'getError' method inside ${this.constructor.name}!`);\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class RequiredValidationError extends BaseValidationError {\n getLocation(dataPath = this.instancePath) {\n const { start } = super.getLocation(dataPath);\n return { start };\n }\n\n print() {\n const { message, params } = this.options;\n const output = [styleText('red', styleText('bold', 'REQUIRED') + ' ' + message) + '\\n'];\n\n return output.concat(\n this.getCodeFrame(\n '☹️ ' + styleText('magentaBright', params.missingProperty) + ' is missing here!'\n )\n );\n }\n\n getError() {\n const { message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(message),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class AdditionalPropValidationError extends BaseValidationError {\n constructor(...args) {\n super(...args);\n this.options.isIdentifierLocation = true;\n }\n\n print() {\n const { message, params } = this.options;\n const output = [\n styleText('red', styleText('bold', 'ADDITIONAL PROPERTY') + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame(\n '😲 ' +\n styleText('magentaBright', params.additionalProperty) +\n ' is not expected to be here!',\n `${this.instancePath}/${params.additionalProperty}`\n )\n );\n }\n\n getError() {\n const { params } = this.options;\n\n return {\n ...this.getLocation(`${this.instancePath}/${params.additionalProperty}`),\n error: this.withDecoratedPath(\n `Property ${params.additionalProperty} is not expected to be here`\n ),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport leven from 'leven';\nimport pointer from 'jsonpointer';\nimport BaseValidationError from './base';\n\nexport default class EnumValidationError extends BaseValidationError {\n print() {\n const {\n message,\n params: { allowedValues },\n } = this.options;\n const bestMatch = this.findBestMatch();\n\n // Needed to handle nullable enums, as joining on null just prints \", \"\n const [firstValue, ...rest] = allowedValues;\n const allowedValuesMessage = rest.reduce((acc, value) => `${acc}, ${value}`, firstValue || '');\n\n const output = [\n styleText('red', styleText('bold', 'ENUM') + ' ' + message),\n styleText('red', `(${allowedValuesMessage})\\n`),\n ];\n\n return output.concat(\n this.getCodeFrame(\n bestMatch !== null\n ? '👈🏽 Did you mean ' + styleText('magentaBright', String(bestMatch)) + ' here?'\n : '👈🏽 Unexpected value, should be equal to one of the allowed values'\n )\n );\n }\n\n getError() {\n const { message, params } = this.options;\n const bestMatch = this.findBestMatch();\n const allowedValues = params.allowedValues.join(', ');\n\n const output = {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${message}: ${allowedValues}`),\n path: this.instancePath,\n };\n\n if (bestMatch !== null) {\n output.suggestion = `Did you mean ${bestMatch}?`;\n }\n\n return output;\n }\n\n findBestMatch() {\n const {\n params: { allowedValues },\n } = this.options;\n\n const currentValue =\n this.instancePath === '' ? this.data : pointer.get(this.data, this.instancePath);\n\n if (!currentValue) {\n return null;\n }\n\n const bestMatch = allowedValues\n .map(value => ({\n value,\n // leven compares strings, so other allowed values cannot be a close match.\n weight: typeof value === 'string' ? leven(value, currentValue.toString()) : Infinity,\n }))\n .sort((x, y) => (x.weight > y.weight ? 1 : x.weight < y.weight ? -1 : 0))[0];\n\n return allowedValues.length === 1 || bestMatch.weight < bestMatch.value.length\n ? bestMatch.value\n : null;\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class DefaultValidationError extends BaseValidationError {\n print() {\n const { keyword, message } = this.options;\n const output = [\n styleText('red', styleText('bold', keyword.toUpperCase()) + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame('👈🏽 ' + styleText('magentaBright', keyword) + ' ' + message)\n );\n }\n\n getError() {\n const { keyword, message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${keyword} ${message}`, ': '),\n path: this.instancePath,\n };\n }\n}\n","import {\n getChildren,\n getErrors,\n getSiblings,\n isAnyOfError,\n isEnumError,\n isRequiredError,\n concatAll,\n notUndefined,\n} from './utils';\nimport {\n AdditionalPropValidationError,\n RequiredValidationError,\n EnumValidationError,\n DefaultValidationError,\n} from './validation-errors/index';\n\nconst JSON_POINTERS_REGEX = /\\/[\\w_-]+(\\/\\d+)?/g;\n\n// Make a tree of errors from ajv errors array\nexport function makeTree(ajvErrors = []) {\n const root = { children: {} };\n ajvErrors.forEach(ajvError => {\n const instancePath =\n typeof ajvError.instancePath !== 'undefined' ? ajvError.instancePath : ajvError.dataPath;\n\n // `dataPath === ''` is root\n const paths = instancePath === '' ? [''] : instancePath.match(JSON_POINTERS_REGEX);\n if (paths) {\n paths.reduce((obj, path, i) => {\n obj.children[path] = obj.children[path] || { children: {}, errors: [] };\n if (i === paths.length - 1) {\n obj.children[path].errors.push(ajvError);\n }\n return obj.children[path];\n }, root);\n }\n });\n return root;\n}\n\nexport function filterRedundantErrors(root, parent, key) {\n /**\n * Partition out the errors by kind for ease of proceessing\n */\n const { anyOfErrors, enumErrors, requiredErrors } = getErrors(root).reduce(\n (acc, error) => {\n if (isRequiredError(error)) {\n acc.requiredErrors.push(error);\n\n return acc;\n }\n\n if (isAnyOfError(error)) {\n acc.anyOfErrors.push(error);\n }\n\n if (isEnumError(error)) {\n acc.enumErrors.push(error);\n }\n\n return acc;\n },\n { anyOfErrors: [], enumErrors: [], requiredErrors: [] }\n );\n\n /**\n * If there is are `required` errors then we can just drop every non-required error.\n * And, also `required` should have more priority than `anyOf`. @see #8\n */\n\n if (requiredErrors.length > 0) {\n root.errors = requiredErrors;\n root.children = {};\n\n // No need for further processing, as we've emptied out children\n return;\n }\n\n /**\n * If there is an `anyOf` error that means we have more meaningful errors\n * inside children. So we will just remove all errors from this level.\n *\n * If there are no children, then we don't delete the errors since we should\n * have at least one error to report.\n */\n if (anyOfErrors.length > 0 && Object.keys(root.children).length > 0) {\n delete root.errors;\n }\n\n /**\n * If all errors are `enum` and siblings have any error then we can safely\n * ignore the node. As we return early if there's required errors, we only\n * need to check anyofErrors length\n *\n * **CAUTION**\n * Need explicit `root.errors` check because `[].every(fn) === true`\n * https://en.wikipedia.org/wiki/Vacuous_truth#Vacuous_truths_in_mathematics\n */\n if (enumErrors.length > 0 && anyOfErrors.length === 0) {\n if (\n getSiblings(parent)(root)\n // Remove any reference which becomes `undefined` later\n .filter(notUndefined)\n .some(getErrors)\n ) {\n delete parent.children[key];\n }\n }\n\n Object.entries(root.children).forEach(([key, child]) => filterRedundantErrors(child, root, key));\n}\n\nexport function createErrorInstances(root, options) {\n const errors = getErrors(root);\n if (errors.length && errors.every(isEnumError)) {\n const uniqueValues = new Set(concatAll([])(errors.map(e => e.params.allowedValues)));\n const allowedValues = [...uniqueValues];\n const error = errors[0];\n return [\n new EnumValidationError(\n {\n ...error,\n params: { allowedValues },\n },\n options\n ),\n ];\n } else {\n return concatAll(\n errors.reduce((ret, error) => {\n switch (error.keyword) {\n case 'additionalProperties':\n return ret.concat(new AdditionalPropValidationError(error, options));\n case 'required':\n return ret.concat(new RequiredValidationError(error, options));\n default:\n return ret.concat(new DefaultValidationError(error, options));\n }\n }, [])\n )(getChildren(root).map(child => createErrorInstances(child, options)));\n }\n}\n\nexport default (ajvErrors, options) => {\n const tree = makeTree(ajvErrors || []);\n filterRedundantErrors(tree);\n return createErrorInstances(tree, options);\n};\n","import { parse } from '@humanwhocodes/momoa';\nimport prettify from './helpers';\n\nexport default (schema, data, errors, options = {}) => {\n const { format = 'cli', indent = null, json = null } = options;\n\n const jsonRaw = json || JSON.stringify(data, null, indent);\n const jsonAst = parse(jsonRaw);\n\n const customErrorToText = error => error.print().join('\\n');\n const customErrorToStructure = error => error.getError();\n const customErrors = prettify(errors, {\n data,\n schema,\n jsonAst,\n jsonRaw,\n });\n\n if (format === 'cli') {\n return customErrors.map(customErrorToText).join('\\n\\n');\n } else {\n return customErrors.map(customErrorToStructure);\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["styleText","tokenize","styleText","styleText","styleText","pointer","styleText","parse","prettify"],"sources":["../src/utils.js","../src/code-frame.js","../src/json/utils.js","../src/json/get-meta-from-path.js","../src/json/get-decorated-data-path.js","../src/validation-errors/base.js","../src/validation-errors/required.js","../src/validation-errors/additional-prop.js","../src/validation-errors/enum.js","../src/validation-errors/default.js","../src/helpers.js","../src/index.js"],"sourcesContent":["// Basic\nconst eq = x => y => x === y;\nconst not = fn => x => !fn(x);\n\nconst getValues = o => Object.values(o);\n\nexport const notUndefined = x => x !== undefined;\n\n// Error\nconst isXError = x => error => error.keyword === x;\nexport const isRequiredError = isXError('required');\nexport const isAnyOfError = isXError('anyOf');\nexport const isEnumError = isXError('enum');\nexport const getErrors = node =>\n node && node.errors\n ? node.errors.map(e =>\n e.keyword === 'errorMessage' ? { ...e.params.errors[0], message: e.message } : e\n )\n : [];\n\n// Node\nexport const getChildren = node => (node && getValues(node.children)) || [];\n\nexport const getSiblings = parent => node => getChildren(parent).filter(not(eq(node)));\n\nexport const concatAll = xs => ys => ys.reduce((zs, z) => zs.concat(z), xs);\n","import { styleText } from 'node:util';\nimport { tokenize } from '@humanwhocodes/momoa';\n\nconst LINES_ABOVE = 2;\nconst LINES_BELOW = 3;\n\n// The line breaks momoa counts, so that its line numbers index into the split source.\nconst NEWLINE = /\\r\\n|[\\r\\n]/;\n\nconst TOKEN_STYLES = {\n String: 'green',\n Number: 'magenta',\n Boolean: 'cyan',\n Null: 'cyan',\n Colon: 'yellow',\n Comma: 'yellow',\n};\n\nconst MARKER_STYLE = ['red', 'bold'];\n\n// The check `styleText` makes for the headings, so that the frame is colored along with them.\nconst supportsColor = () => styleText('red', '-') !== '-';\n\n/**\n * Renders the lines of `source` around `location`, with carets under the located text and\n * `message` after the last caret.\n *\n * Lines and columns are 1-based and `end` is exclusive, as in momoa's locations. Without\n * `end`, a single caret marks `start`.\n *\n * @param {string} source\n * @param {{ start: { line: number, column: number }, end?: { line: number, column: number } }} location\n * @param {{ message?: string, color?: boolean }} [options]\n * @return {string}\n */\nexport default function codeFrame(\n source,\n { start, end = start },\n { message, color = supportsColor() } = {}\n) {\n const paint = color\n ? (format, text) => styleText(format, text, { validateStream: false })\n : (_format, text) => text;\n\n const lines = source.split(NEWLINE);\n const markers = getMarkers(lines, start, end);\n const first = Math.max(start.line - LINES_ABOVE, 1);\n const last = Math.min(end.line + LINES_BELOW, lines.length);\n const width = String(last).length;\n\n const rows = [];\n for (let number = first; number <= last; number++) {\n const line = lines[number - 1];\n const gutter = ` ${String(number).padStart(width)} |`;\n const code = line.length > 0 ? ` ${color ? highlight(line, paint) : line}` : '';\n const marker = markers.get(number);\n if (!marker) {\n rows.push(` ${paint('gray', gutter)}${code}`);\n continue;\n }\n\n const [column, count] = marker;\n const spacing = line.slice(0, column - 1).replace(/[^\\t]/g, ' ');\n let caretRow = ` ${paint('gray', gutter.replace(/\\d/g, ' '))} ${spacing}${paint(MARKER_STYLE, '^'.repeat(count))}`;\n if (message && number === end.line) {\n caretRow += ` ${paint(MARKER_STYLE, message)}`;\n }\n rows.push(`${paint(MARKER_STYLE, '>')}${paint('gray', gutter)}${code}`, caretRow);\n }\n\n return rows.join('\\n');\n}\n\n// Maps each marked line number to the column of its first caret and the number of carets.\nfunction getMarkers(lines, start, end) {\n const markers = new Map();\n if (start.line === end.line) {\n markers.set(start.line, [start.column, Math.max(end.column - start.column, 1)]);\n return markers;\n }\n\n markers.set(start.line, [start.column, lines[start.line - 1].length - start.column + 1]);\n for (let number = start.line + 1; number < end.line; number++) {\n markers.set(number, [1, Math.max(lines[number - 1].length, 1)]);\n }\n markers.set(end.line, [1, end.column - 1]);\n return markers;\n}\n\n// JSON strings can't contain raw line breaks, so each line holds whole tokens.\nfunction highlight(line, paint) {\n let output = '';\n let offset = 0;\n for (const { type, loc } of tokenize(line)) {\n const style = TOKEN_STYLES[type];\n if (style) {\n output +=\n line.slice(offset, loc.start.offset) +\n paint(style, line.slice(loc.start.offset, loc.end.offset));\n offset = loc.end.offset;\n }\n }\n return output + line.slice(offset);\n}\n","// TODO: Better error handling\nexport const getPointers = dataPath => {\n return dataPath\n .split('/')\n .slice(1)\n .map(pointer => pointer.split('~1').join('/').split('~0').join('~'));\n};\n","import { getPointers } from './utils';\n\nexport default function getMetaFromPath(jsonAst, dataPath, includeIdentifierLocation) {\n const pointers = getPointers(dataPath);\n const lastPointerIndex = pointers.length - 1;\n return pointers.reduce((obj, pointer, idx) => {\n switch (obj.type) {\n case 'Object': {\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n\n const { name, value } = member;\n return includeIdentifierLocation && idx === lastPointerIndex ? name : value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n return element && element.value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n}\n","import { getPointers } from './utils';\n\nexport default function getDecoratedDataPath(jsonAst, dataPath) {\n let decoratedPath = '';\n getPointers(dataPath).reduce((obj, pointer) => {\n switch (obj.type) {\n case 'Object': {\n decoratedPath += `/${pointer}`;\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n return member.value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n const value = element && element.value;\n decoratedPath += `/${pointer}${getTypeName(value)}`;\n return value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n return decoratedPath;\n}\n\nfunction getTypeName(obj) {\n if (!obj || !obj.elements) {\n return '';\n }\n const type = obj.elements.filter(child => child && child.name && child.name.value === 'type');\n\n if (!type.length) {\n return '';\n }\n\n return (type[0].value && `:${type[0].value.value}`) || '';\n}\n","import codeFrame from '../code-frame';\nimport { getMetaFromPath, getDecoratedDataPath } from '../json/index';\n\nexport default class BaseValidationError {\n constructor(options = { isIdentifierLocation: false }, { data, schema, jsonAst, jsonRaw }) {\n this.options = options;\n this.data = data;\n this.schema = schema;\n this.jsonAst = jsonAst;\n this.jsonRaw = jsonRaw;\n }\n\n getLocation(dataPath = this.instancePath) {\n const { isIdentifierLocation, isSkipEndLocation } = this.options;\n const { loc } = getMetaFromPath(this.jsonAst, dataPath, isIdentifierLocation);\n return {\n start: loc.start,\n end: isSkipEndLocation ? undefined : loc.end,\n };\n }\n\n getDecoratedPath(dataPath = this.instancePath) {\n const decoratedPath = getDecoratedDataPath(this.jsonAst, dataPath);\n return decoratedPath;\n }\n\n // The decorated path is empty at the root, where the message stands alone.\n withDecoratedPath(message, separator = ' ') {\n const decoratedPath = this.getDecoratedPath();\n return decoratedPath ? `${decoratedPath}${separator}${message}` : message;\n }\n\n getCodeFrame(message, dataPath = this.instancePath) {\n return codeFrame(this.jsonRaw, this.getLocation(dataPath), { message });\n }\n\n /**\n * @return {string}\n */\n get instancePath() {\n return typeof this.options.instancePath !== 'undefined'\n ? this.options.instancePath\n : this.options.dataPath;\n }\n\n print() {\n throw new Error(`Implement the 'print' method inside ${this.constructor.name}!`);\n }\n\n getError() {\n throw new Error(`Implement the 'getError' method inside ${this.constructor.name}!`);\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class RequiredValidationError extends BaseValidationError {\n getLocation(dataPath = this.instancePath) {\n const { start } = super.getLocation(dataPath);\n return { start };\n }\n\n print() {\n const { message, params } = this.options;\n const output = [styleText('red', styleText('bold', 'REQUIRED') + ' ' + message) + '\\n'];\n\n return output.concat(\n this.getCodeFrame(\n '☹️ ' + styleText('magentaBright', params.missingProperty) + ' is missing here!'\n )\n );\n }\n\n getError() {\n const { message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(message),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class AdditionalPropValidationError extends BaseValidationError {\n constructor(...args) {\n super(...args);\n this.options.isIdentifierLocation = true;\n }\n\n print() {\n const { message, params } = this.options;\n const output = [\n styleText('red', styleText('bold', 'ADDITIONAL PROPERTY') + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame(\n '😲 ' +\n styleText('magentaBright', params.additionalProperty) +\n ' is not expected to be here!',\n `${this.instancePath}/${params.additionalProperty}`\n )\n );\n }\n\n getError() {\n const { params } = this.options;\n\n return {\n ...this.getLocation(`${this.instancePath}/${params.additionalProperty}`),\n error: this.withDecoratedPath(\n `Property ${params.additionalProperty} is not expected to be here`\n ),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport leven from 'leven';\nimport pointer from 'jsonpointer';\nimport BaseValidationError from './base';\n\nexport default class EnumValidationError extends BaseValidationError {\n print() {\n const {\n message,\n params: { allowedValues },\n } = this.options;\n const bestMatch = this.findBestMatch();\n\n // Needed to handle nullable enums, as joining on null just prints \", \"\n const [firstValue, ...rest] = allowedValues;\n const allowedValuesMessage = rest.reduce((acc, value) => `${acc}, ${value}`, firstValue || '');\n\n const output = [\n styleText('red', styleText('bold', 'ENUM') + ' ' + message),\n styleText('red', `(${allowedValuesMessage})\\n`),\n ];\n\n return output.concat(\n this.getCodeFrame(\n bestMatch !== null\n ? '👈🏽 Did you mean ' + styleText('magentaBright', String(bestMatch)) + ' here?'\n : '👈🏽 Unexpected value, should be equal to one of the allowed values'\n )\n );\n }\n\n getError() {\n const { message, params } = this.options;\n const bestMatch = this.findBestMatch();\n const allowedValues = params.allowedValues.join(', ');\n\n const output = {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${message}: ${allowedValues}`),\n path: this.instancePath,\n };\n\n if (bestMatch !== null) {\n output.suggestion = `Did you mean ${bestMatch}?`;\n }\n\n return output;\n }\n\n findBestMatch() {\n const {\n params: { allowedValues },\n } = this.options;\n\n const currentValue =\n this.instancePath === '' ? this.data : pointer.get(this.data, this.instancePath);\n\n if (!currentValue) {\n return null;\n }\n\n const bestMatch = allowedValues\n .map(value => ({\n value,\n // leven compares strings, so other allowed values cannot be a close match.\n weight: typeof value === 'string' ? leven(value, currentValue.toString()) : Infinity,\n }))\n .sort((x, y) => (x.weight > y.weight ? 1 : x.weight < y.weight ? -1 : 0))[0];\n\n return allowedValues.length === 1 || bestMatch.weight < bestMatch.value.length\n ? bestMatch.value\n : null;\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class DefaultValidationError extends BaseValidationError {\n print() {\n const { keyword, message } = this.options;\n const output = [\n styleText('red', styleText('bold', keyword.toUpperCase()) + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame('👈🏽 ' + styleText('magentaBright', keyword) + ' ' + message)\n );\n }\n\n getError() {\n const { keyword, message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${keyword} ${message}`, ': '),\n path: this.instancePath,\n };\n }\n}\n","import {\n getChildren,\n getErrors,\n getSiblings,\n isAnyOfError,\n isEnumError,\n isRequiredError,\n concatAll,\n notUndefined,\n} from './utils';\nimport {\n AdditionalPropValidationError,\n RequiredValidationError,\n EnumValidationError,\n DefaultValidationError,\n} from './validation-errors/index';\n\nconst JSON_POINTERS_REGEX = /\\/[\\w_-]+(\\/\\d+)?/g;\n\n// Make a tree of errors from ajv errors array\nexport function makeTree(ajvErrors = []) {\n const root = { children: {} };\n ajvErrors.forEach(ajvError => {\n const instancePath =\n typeof ajvError.instancePath !== 'undefined' ? ajvError.instancePath : ajvError.dataPath;\n\n // `dataPath === ''` is root\n const paths = instancePath === '' ? [''] : instancePath.match(JSON_POINTERS_REGEX);\n if (paths) {\n paths.reduce((obj, path, i) => {\n obj.children[path] = obj.children[path] || { children: {}, errors: [] };\n if (i === paths.length - 1) {\n obj.children[path].errors.push(ajvError);\n }\n return obj.children[path];\n }, root);\n }\n });\n return root;\n}\n\nexport function filterRedundantErrors(root, parent, key) {\n /**\n * Partition out the errors by kind for ease of proceessing\n */\n const { anyOfErrors, enumErrors, requiredErrors } = getErrors(root).reduce(\n (acc, error) => {\n if (isRequiredError(error)) {\n acc.requiredErrors.push(error);\n\n return acc;\n }\n\n if (isAnyOfError(error)) {\n acc.anyOfErrors.push(error);\n }\n\n if (isEnumError(error)) {\n acc.enumErrors.push(error);\n }\n\n return acc;\n },\n { anyOfErrors: [], enumErrors: [], requiredErrors: [] }\n );\n\n /**\n * If there is are `required` errors then we can just drop every non-required error.\n * And, also `required` should have more priority than `anyOf`. @see #8\n */\n\n if (requiredErrors.length > 0) {\n root.errors = requiredErrors;\n root.children = {};\n\n // No need for further processing, as we've emptied out children\n return;\n }\n\n /**\n * If there is an `anyOf` error that means we have more meaningful errors\n * inside children. So we will just remove all errors from this level.\n *\n * If there are no children, then we don't delete the errors since we should\n * have at least one error to report.\n */\n if (anyOfErrors.length > 0 && Object.keys(root.children).length > 0) {\n delete root.errors;\n }\n\n /**\n * If all errors are `enum` and siblings have any error then we can safely\n * ignore the node. As we return early if there's required errors, we only\n * need to check anyofErrors length\n *\n * **CAUTION**\n * Need explicit `root.errors` check because `[].every(fn) === true`\n * https://en.wikipedia.org/wiki/Vacuous_truth#Vacuous_truths_in_mathematics\n */\n if (enumErrors.length > 0 && anyOfErrors.length === 0) {\n if (\n getSiblings(parent)(root)\n // Remove any reference which becomes `undefined` later\n .filter(notUndefined)\n .some(getErrors)\n ) {\n delete parent.children[key];\n }\n }\n\n Object.entries(root.children).forEach(([key, child]) => filterRedundantErrors(child, root, key));\n}\n\nexport function createErrorInstances(root, options) {\n const errors = getErrors(root);\n if (errors.length && errors.every(isEnumError)) {\n const uniqueValues = new Set(concatAll([])(errors.map(e => e.params.allowedValues)));\n const allowedValues = [...uniqueValues];\n const error = errors[0];\n return [\n new EnumValidationError(\n {\n ...error,\n params: { allowedValues },\n },\n options\n ),\n ];\n } else {\n return concatAll(\n errors.reduce((ret, error) => {\n switch (error.keyword) {\n case 'additionalProperties':\n return ret.concat(new AdditionalPropValidationError(error, options));\n case 'required':\n return ret.concat(new RequiredValidationError(error, options));\n default:\n return ret.concat(new DefaultValidationError(error, options));\n }\n }, [])\n )(getChildren(root).map(child => createErrorInstances(child, options)));\n }\n}\n\nexport default (ajvErrors, options) => {\n const tree = makeTree(ajvErrors || []);\n filterRedundantErrors(tree);\n return createErrorInstances(tree, options);\n};\n","import { parse } from '@humanwhocodes/momoa';\nimport prettify from './helpers';\n\nexport default (schema, data, errors, options = {}) => {\n const { format = 'cli', indent = null, json = null } = options;\n\n const jsonRaw = json || JSON.stringify(data, null, indent);\n const jsonAst = parse(jsonRaw);\n\n const customErrorToText = error => error.print().join('\\n');\n const customErrorToStructure = error => error.getError();\n const customErrors = prettify(errors, {\n data,\n schema,\n jsonAst,\n jsonRaw,\n });\n\n if (format === 'cli') {\n return customErrors.map(customErrorToText).join('\\n\\n');\n } else {\n return customErrors.map(customErrorToStructure);\n }\n};\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,MAAM,MAAK,OAAK,MAAK,MAAM;AAC3B,MAAM,OAAM,QAAM,MAAK,CAAC,GAAG,CAAC;AAE5B,MAAM,aAAY,MAAK,OAAO,OAAO,CAAC;AAEtC,MAAa,gBAAe,MAAK,MAAM,KAAA;AAGvC,MAAM,YAAW,OAAK,UAAS,MAAM,YAAY;AACjD,MAAa,kBAAkB,SAAS,UAAU;AAClD,MAAa,eAAe,SAAS,OAAO;AAC5C,MAAa,cAAc,SAAS,MAAM;AAC1C,MAAa,aAAY,SACvB,QAAQ,KAAK,SACT,KAAK,OAAO,KAAI,MACd,EAAE,YAAY,iBAAiB;CAAE,GAAG,EAAE,OAAO,OAAO;CAAI,SAAS,EAAE;AAAQ,IAAI,CACjF,IACA,CAAC;AAGP,MAAa,eAAc,SAAS,QAAQ,UAAU,KAAK,QAAQ,KAAM,CAAC;AAE1E,MAAa,eAAc,YAAU,SAAQ,YAAY,MAAM,CAAC,CAAC,OAAO,IAAI,GAAG,IAAI,CAAC,CAAC;AAErF,MAAa,aAAY,QAAM,OAAM,GAAG,QAAQ,IAAI,MAAM,GAAG,OAAO,CAAC,GAAG,EAAE;;;ACtB1E,MAAM,cAAc;AACpB,MAAM,cAAc;AAGpB,MAAM,UAAU;AAEhB,MAAM,eAAe;CACnB,QAAQ;CACR,QAAQ;CACR,SAAS;CACT,MAAM;CACN,OAAO;CACP,OAAO;AACT;AAEA,MAAM,eAAe,CAAC,OAAO,MAAM;AAGnC,MAAM,uBAAA,GAAsBA,UAAAA,UAAAA,CAAU,OAAO,GAAG,MAAM;;;;;;;;;;;;;AActD,SAAwB,UACtB,QACA,EAAE,OAAO,MAAM,SACf,EAAE,SAAS,QAAQ,cAAc,MAAM,CAAC,GACxC;CACA,MAAM,QAAQ,SACT,QAAQ,UAAA,GAASA,UAAAA,UAAAA,CAAU,QAAQ,MAAM,EAAE,gBAAgB,MAAM,CAAC,KAClE,SAAS,SAAS;CAEvB,MAAM,QAAQ,OAAO,MAAM,OAAO;CAClC,MAAM,UAAU,WAAW,OAAO,OAAO,GAAG;CAC5C,MAAM,QAAQ,KAAK,IAAI,MAAM,OAAO,aAAa,CAAC;CAClD,MAAM,OAAO,KAAK,IAAI,IAAI,OAAO,aAAa,MAAM,MAAM;CAC1D,MAAM,QAAQ,OAAO,IAAI,CAAC,CAAC;CAE3B,MAAM,OAAO,CAAC;CACd,KAAK,IAAI,SAAS,OAAO,UAAU,MAAM,UAAU;EACjD,MAAM,OAAO,MAAM,SAAS;EAC5B,MAAM,SAAS,IAAI,OAAO,MAAM,CAAC,CAAC,SAAS,KAAK,EAAE;EAClD,MAAM,OAAO,KAAK,SAAS,IAAI,IAAI,QAAQ,UAAU,MAAM,KAAK,IAAI,SAAS;EAC7E,MAAM,SAAS,QAAQ,IAAI,MAAM;EACjC,IAAI,CAAC,QAAQ;GACX,KAAK,KAAK,IAAI,MAAM,QAAQ,MAAM,IAAI,MAAM;GAC5C;EACF;EAEA,MAAM,CAAC,QAAQ,SAAS;EACxB,MAAM,UAAU,KAAK,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,UAAU,GAAG;EAC/D,IAAI,WAAW,IAAI,MAAM,QAAQ,OAAO,QAAQ,OAAO,GAAG,CAAC,EAAE,GAAG,UAAU,MAAM,cAAc,IAAI,OAAO,KAAK,CAAC;EAC/G,IAAI,WAAW,WAAW,IAAI,MAC5B,YAAY,IAAI,MAAM,cAAc,OAAO;EAE7C,KAAK,KAAK,GAAG,MAAM,cAAc,GAAG,IAAI,MAAM,QAAQ,MAAM,IAAI,QAAQ,QAAQ;CAClF;CAEA,OAAO,KAAK,KAAK,IAAI;AACvB;AAGA,SAAS,WAAW,OAAO,OAAO,KAAK;CACrC,MAAM,0BAAU,IAAI,IAAI;CACxB,IAAI,MAAM,SAAS,IAAI,MAAM;EAC3B,QAAQ,IAAI,MAAM,MAAM,CAAC,MAAM,QAAQ,KAAK,IAAI,IAAI,SAAS,MAAM,QAAQ,CAAC,CAAC,CAAC;EAC9E,OAAO;CACT;CAEA,QAAQ,IAAI,MAAM,MAAM,CAAC,MAAM,QAAQ,MAAM,MAAM,OAAO,EAAE,CAAC,SAAS,MAAM,SAAS,CAAC,CAAC;CACvF,KAAK,IAAI,SAAS,MAAM,OAAO,GAAG,SAAS,IAAI,MAAM,UACnD,QAAQ,IAAI,QAAQ,CAAC,GAAG,KAAK,IAAI,MAAM,SAAS,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;CAEhE,QAAQ,IAAI,IAAI,MAAM,CAAC,GAAG,IAAI,SAAS,CAAC,CAAC;CACzC,OAAO;AACT;AAGA,SAAS,UAAU,MAAM,OAAO;CAC9B,IAAI,SAAS;CACb,IAAI,SAAS;CACb,KAAK,MAAM,EAAE,MAAM,UAAA,GAASC,qBAAAA,SAAAA,CAAS,IAAI,GAAG;EAC1C,MAAM,QAAQ,aAAa;EAC3B,IAAI,OAAO;GACT,UACE,KAAK,MAAM,QAAQ,IAAI,MAAM,MAAM,IACnC,MAAM,OAAO,KAAK,MAAM,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,CAAC;GAC3D,SAAS,IAAI,IAAI;EACnB;CACF;CACA,OAAO,SAAS,KAAK,MAAM,MAAM;AACnC;;;ACtGA,MAAa,eAAc,aAAY;CACrC,OAAO,SACJ,MAAM,GAAG,CAAC,CACV,MAAM,CAAC,CAAC,CACR,KAAI,YAAW,QAAQ,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC;AACvE;;;ACJA,SAAwB,gBAAgB,SAAS,UAAU,2BAA2B;CACpF,MAAM,WAAW,YAAY,QAAQ;CACrC,MAAM,mBAAmB,SAAS,SAAS;CAC3C,OAAO,SAAS,QAAQ,KAAK,SAAS,QAAQ;EAC5C,QAAQ,IAAI,MAAZ;GACE,KAAK,UAAU;IAEb,MAAM,SAAS,IAAI,QAAQ,UAAS,UAAS,MAAM,KAAK,UAAU,OAAO;IACzE,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,0BAA0B,QAAQ,MAAM,UAAU;IAGpE,MAAM,EAAE,MAAM,UAAU;IACxB,OAAO,6BAA6B,QAAQ,mBAAmB,OAAO;GACxE;GACA,KAAK,SAAS;IACZ,MAAM,UAAU,IAAI,SAAS;IAC7B,OAAO,WAAW,QAAQ;GAC5B;GACA,SACE,QAAQ,IAAI,GAAG;EACnB;CACF,GAAG,QAAQ,IAAI;AACjB;;;ACvBA,SAAwB,qBAAqB,SAAS,UAAU;CAC9D,IAAI,gBAAgB;CACpB,YAAY,QAAQ,CAAC,CAAC,QAAQ,KAAK,YAAY;EAC7C,QAAQ,IAAI,MAAZ;GACE,KAAK,UAAU;IACb,iBAAiB,IAAI;IAErB,MAAM,SAAS,IAAI,QAAQ,UAAS,UAAS,MAAM,KAAK,UAAU,OAAO;IACzE,IAAI,CAAC,QACH,MAAM,IAAI,MAAM,0BAA0B,QAAQ,MAAM,UAAU;IAEpE,OAAO,OAAO;GAChB;GACA,KAAK,SAAS;IACZ,MAAM,UAAU,IAAI,SAAS;IAC7B,MAAM,QAAQ,WAAW,QAAQ;IACjC,iBAAiB,IAAI,UAAU,YAAY,KAAK;IAChD,OAAO;GACT;GACA,SACE,QAAQ,IAAI,GAAG;EACnB;CACF,GAAG,QAAQ,IAAI;CACf,OAAO;AACT;AAEA,SAAS,YAAY,KAAK;CACxB,IAAI,CAAC,OAAO,CAAC,IAAI,UACf,OAAO;CAET,MAAM,OAAO,IAAI,SAAS,QAAO,UAAS,SAAS,MAAM,QAAQ,MAAM,KAAK,UAAU,MAAM;CAE5F,IAAI,CAAC,KAAK,QACR,OAAO;CAGT,OAAQ,KAAK,EAAE,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC,MAAM,WAAY;AACzD;;;ACpCA,IAAqB,sBAArB,MAAyC;CACvC,YAAY,UAAU,EAAE,sBAAsB,MAAM,GAAG,EAAE,MAAM,QAAQ,SAAS,WAAW;EACzF,KAAK,UAAU;EACf,KAAK,OAAO;EACZ,KAAK,SAAS;EACd,KAAK,UAAU;EACf,KAAK,UAAU;CACjB;CAEA,YAAY,WAAW,KAAK,cAAc;EACxC,MAAM,EAAE,sBAAsB,sBAAsB,KAAK;EACzD,MAAM,EAAE,QAAQ,gBAAgB,KAAK,SAAS,UAAU,oBAAoB;EAC5E,OAAO;GACL,OAAO,IAAI;GACX,KAAK,oBAAoB,KAAA,IAAY,IAAI;EAC3C;CACF;CAEA,iBAAiB,WAAW,KAAK,cAAc;EAE7C,OADsB,qBAAqB,KAAK,SAAS,QACtC;CACrB;CAGA,kBAAkB,SAAS,YAAY,KAAK;EAC1C,MAAM,gBAAgB,KAAK,iBAAiB;EAC5C,OAAO,gBAAgB,GAAG,gBAAgB,YAAY,YAAY;CACpE;CAEA,aAAa,SAAS,WAAW,KAAK,cAAc;EAClD,OAAO,UAAU,KAAK,SAAS,KAAK,YAAY,QAAQ,GAAG,EAAE,QAAQ,CAAC;CACxE;;;;CAKA,IAAI,eAAe;EACjB,OAAO,OAAO,KAAK,QAAQ,iBAAiB,cACxC,KAAK,QAAQ,eACb,KAAK,QAAQ;CACnB;CAEA,QAAQ;EACN,MAAM,IAAI,MAAM,uCAAuC,KAAK,YAAY,KAAK,EAAE;CACjF;CAEA,WAAW;EACT,MAAM,IAAI,MAAM,0CAA0C,KAAK,YAAY,KAAK,EAAE;CACpF;AACF;;;ACjDA,IAAqB,0BAArB,cAAqD,oBAAoB;CACvE,YAAY,WAAW,KAAK,cAAc;EACxC,MAAM,EAAE,UAAU,MAAM,YAAY,QAAQ;EAC5C,OAAO,EAAE,MAAM;CACjB;CAEA,QAAQ;EACN,MAAM,EAAE,SAAS,WAAW,KAAK;EAGjC,OAAO,EAAA,GAFSC,UAAAA,UAAAA,CAAU,QAAA,GAAOA,UAAAA,UAAAA,CAAU,QAAQ,UAAU,IAAI,MAAM,OAAO,IAAI,IAEtE,CAAC,CAAC,OACZ,KAAK,aACH,UAAA,GAASA,UAAAA,UAAAA,CAAU,iBAAiB,OAAO,eAAe,IAAI,mBAChE,CACF;CACF;CAEA,WAAW;EACT,MAAM,EAAE,YAAY,KAAK;EAEzB,OAAO;GACL,GAAG,KAAK,YAAY;GACpB,OAAO,KAAK,kBAAkB,OAAO;GACrC,MAAM,KAAK;EACb;CACF;AACF;;;AC1BA,IAAqB,gCAArB,cAA2D,oBAAoB;CAC7E,YAAY,GAAG,MAAM;EACnB,MAAM,GAAG,IAAI;EACb,KAAK,QAAQ,uBAAuB;CACtC;CAEA,QAAQ;EACN,MAAM,EAAE,SAAS,WAAW,KAAK;EAKjC,OAAO,EAAA,GAHLC,UAAAA,UAAAA,CAAU,QAAA,GAAOA,UAAAA,UAAAA,CAAU,QAAQ,qBAAqB,IAAI,MAAM,OAAO,IAAI,IAGnE,CAAC,CAAC,OACZ,KAAK,aACH,UAAA,GACEA,UAAAA,UAAAA,CAAU,iBAAiB,OAAO,kBAAkB,IACpD,gCACF,GAAG,KAAK,aAAa,GAAG,OAAO,oBACjC,CACF;CACF;CAEA,WAAW;EACT,MAAM,EAAE,WAAW,KAAK;EAExB,OAAO;GACL,GAAG,KAAK,YAAY,GAAG,KAAK,aAAa,GAAG,OAAO,oBAAoB;GACvE,OAAO,KAAK,kBACV,YAAY,OAAO,mBAAmB,4BACxC;GACA,MAAM,KAAK;EACb;CACF;AACF;;;AC/BA,IAAqB,sBAArB,cAAiD,oBAAoB;CACnE,QAAQ;EACN,MAAM,EACJ,SACA,QAAQ,EAAE,oBACR,KAAK;EACT,MAAM,YAAY,KAAK,cAAc;EAGrC,MAAM,CAAC,YAAY,GAAG,QAAQ;EAC9B,MAAM,uBAAuB,KAAK,QAAQ,KAAK,UAAU,GAAG,IAAI,IAAI,SAAS,cAAc,EAAE;EAO7F,OAAO,EAAA,GAJLC,UAAAA,UAAAA,CAAU,QAAA,GAAOA,UAAAA,UAAAA,CAAU,QAAQ,MAAM,IAAI,MAAM,OAAO,IAAA,GAC1DA,UAAAA,UAAAA,CAAU,OAAO,IAAI,qBAAqB,IAAI,CAGpC,CAAC,CAAC,OACZ,KAAK,aACH,cAAc,OACV,yBAAA,GAAwBA,UAAAA,UAAAA,CAAU,iBAAiB,OAAO,SAAS,CAAC,IAAI,WACxE,sEACN,CACF;CACF;CAEA,WAAW;EACT,MAAM,EAAE,SAAS,WAAW,KAAK;EACjC,MAAM,YAAY,KAAK,cAAc;EACrC,MAAM,gBAAgB,OAAO,cAAc,KAAK,IAAI;EAEpD,MAAM,SAAS;GACb,GAAG,KAAK,YAAY;GACpB,OAAO,KAAK,kBAAkB,GAAG,QAAQ,IAAI,eAAe;GAC5D,MAAM,KAAK;EACb;EAEA,IAAI,cAAc,MAChB,OAAO,aAAa,gBAAgB,UAAU;EAGhD,OAAO;CACT;CAEA,gBAAgB;EACd,MAAM,EACJ,QAAQ,EAAE,oBACR,KAAK;EAET,MAAM,eACJ,KAAK,iBAAiB,KAAK,KAAK,OAAOC,YAAAA,QAAQ,IAAI,KAAK,MAAM,KAAK,YAAY;EAEjF,IAAI,CAAC,cACH,OAAO;EAGT,MAAM,YAAY,cACf,KAAI,WAAU;GACb;GAEA,QAAQ,OAAO,UAAU,YAAA,GAAW,MAAA,QAAA,CAAM,OAAO,aAAa,SAAS,CAAC,IAAI;EAC9E,EAAE,CAAC,CACF,MAAM,GAAG,MAAO,EAAE,SAAS,EAAE,SAAS,IAAI,EAAE,SAAS,EAAE,SAAS,KAAK,CAAE,CAAC,CAAC;EAE5E,OAAO,cAAc,WAAW,KAAK,UAAU,SAAS,UAAU,MAAM,SACpE,UAAU,QACV;CACN;AACF;;;ACtEA,IAAqB,yBAArB,cAAoD,oBAAoB;CACtE,QAAQ;EACN,MAAM,EAAE,SAAS,YAAY,KAAK;EAKlC,OAAO,EAAA,GAHLC,UAAAA,UAAAA,CAAU,QAAA,GAAOA,UAAAA,UAAAA,CAAU,QAAQ,QAAQ,YAAY,CAAC,IAAI,MAAM,OAAO,IAAI,IAGnE,CAAC,CAAC,OACZ,KAAK,aAAa,YAAA,GAAWA,UAAAA,UAAAA,CAAU,iBAAiB,OAAO,IAAI,MAAM,OAAO,CAClF;CACF;CAEA,WAAW;EACT,MAAM,EAAE,SAAS,YAAY,KAAK;EAElC,OAAO;GACL,GAAG,KAAK,YAAY;GACpB,OAAO,KAAK,kBAAkB,GAAG,QAAQ,GAAG,WAAW,IAAI;GAC3D,MAAM,KAAK;EACb;CACF;AACF;;;ACPA,MAAM,sBAAsB;AAG5B,SAAgB,SAAS,YAAY,CAAC,GAAG;CACvC,MAAM,OAAO,EAAE,UAAU,CAAC,EAAE;CAC5B,UAAU,SAAQ,aAAY;EAC5B,MAAM,eACJ,OAAO,SAAS,iBAAiB,cAAc,SAAS,eAAe,SAAS;EAGlF,MAAM,QAAQ,iBAAiB,KAAK,CAAC,EAAE,IAAI,aAAa,MAAM,mBAAmB;EACjF,IAAI,OACF,MAAM,QAAQ,KAAK,MAAM,MAAM;GAC7B,IAAI,SAAS,QAAQ,IAAI,SAAS,SAAS;IAAE,UAAU,CAAC;IAAG,QAAQ,CAAC;GAAE;GACtE,IAAI,MAAM,MAAM,SAAS,GACvB,IAAI,SAAS,KAAK,CAAC,OAAO,KAAK,QAAQ;GAEzC,OAAO,IAAI,SAAS;EACtB,GAAG,IAAI;CAEX,CAAC;CACD,OAAO;AACT;AAEA,SAAgB,sBAAsB,MAAM,QAAQ,KAAK;;;;CAIvD,MAAM,EAAE,aAAa,YAAY,mBAAmB,UAAU,IAAI,CAAC,CAAC,QACjE,KAAK,UAAU;EACd,IAAI,gBAAgB,KAAK,GAAG;GAC1B,IAAI,eAAe,KAAK,KAAK;GAE7B,OAAO;EACT;EAEA,IAAI,aAAa,KAAK,GACpB,IAAI,YAAY,KAAK,KAAK;EAG5B,IAAI,YAAY,KAAK,GACnB,IAAI,WAAW,KAAK,KAAK;EAG3B,OAAO;CACT,GACA;EAAE,aAAa,CAAC;EAAG,YAAY,CAAC;EAAG,gBAAgB,CAAC;CAAE,CACxD;;;;;CAOA,IAAI,eAAe,SAAS,GAAG;EAC7B,KAAK,SAAS;EACd,KAAK,WAAW,CAAC;EAGjB;CACF;;;;;;;;CASA,IAAI,YAAY,SAAS,KAAK,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,SAAS,GAChE,OAAO,KAAK;;;;;;;;;;CAYd,IAAI,WAAW,SAAS,KAAK,YAAY,WAAW,GAEhD;MAAA,YAAY,MAAM,CAAC,CAAC,IAAI,CAAC,CAEtB,OAAO,YAAY,CAAC,CACpB,KAAK,SAAS,GAEjB,OAAO,OAAO,SAAS;CAAA;CAI3B,OAAO,QAAQ,KAAK,QAAQ,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW,sBAAsB,OAAO,MAAM,GAAG,CAAC;AACjG;AAEA,SAAgB,qBAAqB,MAAM,SAAS;CAClD,MAAM,SAAS,UAAU,IAAI;CAC7B,IAAI,OAAO,UAAU,OAAO,MAAM,WAAW,GAAG;EAE9C,MAAM,gBAAgB,CAAC,GAAG,IADD,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC,OAAO,KAAI,MAAK,EAAE,OAAO,aAAa,CAAC,CAC7C,CAAC;EACtC,MAAM,QAAQ,OAAO;EACrB,OAAO,CACL,IAAI,oBACF;GACE,GAAG;GACH,QAAQ,EAAE,cAAc;EAC1B,GACA,OACF,CACF;CACF,OACE,OAAO,UACL,OAAO,QAAQ,KAAK,UAAU;EAC5B,QAAQ,MAAM,SAAd;GACE,KAAK,wBACH,OAAO,IAAI,OAAO,IAAI,8BAA8B,OAAO,OAAO,CAAC;GACrE,KAAK,YACH,OAAO,IAAI,OAAO,IAAI,wBAAwB,OAAO,OAAO,CAAC;GAC/D,SACE,OAAO,IAAI,OAAO,IAAI,uBAAuB,OAAO,OAAO,CAAC;EAChE;CACF,GAAG,CAAC,CAAC,CACP,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,KAAI,UAAS,qBAAqB,OAAO,OAAO,CAAC,CAAC;AAE1E;AAEA,IAAA,mBAAgB,WAAW,YAAY;CACrC,MAAM,OAAO,SAAS,aAAa,CAAC,CAAC;CACrC,sBAAsB,IAAI;CAC1B,OAAO,qBAAqB,MAAM,OAAO;AAC3C;;;ACjJA,IAAA,eAAgB,QAAQ,MAAM,QAAQ,UAAU,CAAC,MAAM;CACrD,MAAM,EAAE,SAAS,OAAO,SAAS,MAAM,OAAO,SAAS;CAEvD,MAAM,UAAU,QAAQ,KAAK,UAAU,MAAM,MAAM,MAAM;CACzD,MAAM,WAAA,GAAUC,qBAAAA,MAAAA,CAAM,OAAO;CAE7B,MAAM,qBAAoB,UAAS,MAAM,MAAM,CAAC,CAAC,KAAK,IAAI;CAC1D,MAAM,0BAAyB,UAAS,MAAM,SAAS;CACvD,MAAM,eAAeC,gBAAS,QAAQ;EACpC;EACA;EACA;EACA;CACF,CAAC;CAED,IAAI,WAAW,OACb,OAAO,aAAa,IAAI,iBAAiB,CAAC,CAAC,KAAK,MAAM;MAEtD,OAAO,aAAa,IAAI,sBAAsB;AAElD"}
package/dist/index.mjs CHANGED
@@ -1,6 +1,5 @@
1
- import { parse } from "@humanwhocodes/momoa";
1
+ import { parse, tokenize } from "@humanwhocodes/momoa";
2
2
  import { styleText } from "node:util";
3
- import { codeFrameColumns } from "@babel/code-frame";
4
3
  import leven from "leven";
5
4
  import pointer from "jsonpointer";
6
5
  //#region src/utils.js
@@ -20,6 +19,81 @@ const getChildren = (node) => node && getValues(node.children) || [];
20
19
  const getSiblings = (parent) => (node) => getChildren(parent).filter(not(eq(node)));
21
20
  const concatAll = (xs) => (ys) => ys.reduce((zs, z) => zs.concat(z), xs);
22
21
  //#endregion
22
+ //#region src/code-frame.js
23
+ const LINES_ABOVE = 2;
24
+ const LINES_BELOW = 3;
25
+ const NEWLINE = /\r\n|[\r\n]/;
26
+ const TOKEN_STYLES = {
27
+ String: "green",
28
+ Number: "magenta",
29
+ Boolean: "cyan",
30
+ Null: "cyan",
31
+ Colon: "yellow",
32
+ Comma: "yellow"
33
+ };
34
+ const MARKER_STYLE = ["red", "bold"];
35
+ const supportsColor = () => styleText("red", "-") !== "-";
36
+ /**
37
+ * Renders the lines of `source` around `location`, with carets under the located text and
38
+ * `message` after the last caret.
39
+ *
40
+ * Lines and columns are 1-based and `end` is exclusive, as in momoa's locations. Without
41
+ * `end`, a single caret marks `start`.
42
+ *
43
+ * @param {string} source
44
+ * @param {{ start: { line: number, column: number }, end?: { line: number, column: number } }} location
45
+ * @param {{ message?: string, color?: boolean }} [options]
46
+ * @return {string}
47
+ */
48
+ function codeFrame(source, { start, end = start }, { message, color = supportsColor() } = {}) {
49
+ const paint = color ? (format, text) => styleText(format, text, { validateStream: false }) : (_format, text) => text;
50
+ const lines = source.split(NEWLINE);
51
+ const markers = getMarkers(lines, start, end);
52
+ const first = Math.max(start.line - LINES_ABOVE, 1);
53
+ const last = Math.min(end.line + LINES_BELOW, lines.length);
54
+ const width = String(last).length;
55
+ const rows = [];
56
+ for (let number = first; number <= last; number++) {
57
+ const line = lines[number - 1];
58
+ const gutter = ` ${String(number).padStart(width)} |`;
59
+ const code = line.length > 0 ? ` ${color ? highlight(line, paint) : line}` : "";
60
+ const marker = markers.get(number);
61
+ if (!marker) {
62
+ rows.push(` ${paint("gray", gutter)}${code}`);
63
+ continue;
64
+ }
65
+ const [column, count] = marker;
66
+ const spacing = line.slice(0, column - 1).replace(/[^\t]/g, " ");
67
+ let caretRow = ` ${paint("gray", gutter.replace(/\d/g, " "))} ${spacing}${paint(MARKER_STYLE, "^".repeat(count))}`;
68
+ if (message && number === end.line) caretRow += ` ${paint(MARKER_STYLE, message)}`;
69
+ rows.push(`${paint(MARKER_STYLE, ">")}${paint("gray", gutter)}${code}`, caretRow);
70
+ }
71
+ return rows.join("\n");
72
+ }
73
+ function getMarkers(lines, start, end) {
74
+ const markers = /* @__PURE__ */ new Map();
75
+ if (start.line === end.line) {
76
+ markers.set(start.line, [start.column, Math.max(end.column - start.column, 1)]);
77
+ return markers;
78
+ }
79
+ markers.set(start.line, [start.column, lines[start.line - 1].length - start.column + 1]);
80
+ for (let number = start.line + 1; number < end.line; number++) markers.set(number, [1, Math.max(lines[number - 1].length, 1)]);
81
+ markers.set(end.line, [1, end.column - 1]);
82
+ return markers;
83
+ }
84
+ function highlight(line, paint) {
85
+ let output = "";
86
+ let offset = 0;
87
+ for (const { type, loc } of tokenize(line)) {
88
+ const style = TOKEN_STYLES[type];
89
+ if (style) {
90
+ output += line.slice(offset, loc.start.offset) + paint(style, line.slice(loc.start.offset, loc.end.offset));
91
+ offset = loc.end.offset;
92
+ }
93
+ }
94
+ return output + line.slice(offset);
95
+ }
96
+ //#endregion
23
97
  //#region src/json/utils.js
24
98
  const getPointers = (dataPath) => {
25
99
  return dataPath.split("/").slice(1).map((pointer) => pointer.split("~1").join("/").split("~0").join("~"));
@@ -100,10 +174,7 @@ var BaseValidationError = class {
100
174
  return decoratedPath ? `${decoratedPath}${separator}${message}` : message;
101
175
  }
102
176
  getCodeFrame(message, dataPath = this.instancePath) {
103
- return codeFrameColumns(this.jsonRaw, this.getLocation(dataPath), {
104
- highlightCode: true,
105
- message
106
- });
177
+ return codeFrame(this.jsonRaw, this.getLocation(dataPath), { message });
107
178
  }
108
179
  /**
109
180
  * @return {string}
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["prettify"],"sources":["../src/utils.js","../src/json/utils.js","../src/json/get-meta-from-path.js","../src/json/get-decorated-data-path.js","../src/validation-errors/base.js","../src/validation-errors/required.js","../src/validation-errors/additional-prop.js","../src/validation-errors/enum.js","../src/validation-errors/default.js","../src/helpers.js","../src/index.js"],"sourcesContent":["// Basic\nconst eq = x => y => x === y;\nconst not = fn => x => !fn(x);\n\nconst getValues = o => Object.values(o);\n\nexport const notUndefined = x => x !== undefined;\n\n// Error\nconst isXError = x => error => error.keyword === x;\nexport const isRequiredError = isXError('required');\nexport const isAnyOfError = isXError('anyOf');\nexport const isEnumError = isXError('enum');\nexport const getErrors = node =>\n node && node.errors\n ? node.errors.map(e =>\n e.keyword === 'errorMessage' ? { ...e.params.errors[0], message: e.message } : e\n )\n : [];\n\n// Node\nexport const getChildren = node => (node && getValues(node.children)) || [];\n\nexport const getSiblings = parent => node => getChildren(parent).filter(not(eq(node)));\n\nexport const concatAll = xs => ys => ys.reduce((zs, z) => zs.concat(z), xs);\n","// TODO: Better error handling\nexport const getPointers = dataPath => {\n return dataPath\n .split('/')\n .slice(1)\n .map(pointer => pointer.split('~1').join('/').split('~0').join('~'));\n};\n","import { getPointers } from './utils';\n\nexport default function getMetaFromPath(jsonAst, dataPath, includeIdentifierLocation) {\n const pointers = getPointers(dataPath);\n const lastPointerIndex = pointers.length - 1;\n return pointers.reduce((obj, pointer, idx) => {\n switch (obj.type) {\n case 'Object': {\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n\n const { name, value } = member;\n return includeIdentifierLocation && idx === lastPointerIndex ? name : value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n return element && element.value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n}\n","import { getPointers } from './utils';\n\nexport default function getDecoratedDataPath(jsonAst, dataPath) {\n let decoratedPath = '';\n getPointers(dataPath).reduce((obj, pointer) => {\n switch (obj.type) {\n case 'Object': {\n decoratedPath += `/${pointer}`;\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n return member.value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n const value = element && element.value;\n decoratedPath += `/${pointer}${getTypeName(value)}`;\n return value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n return decoratedPath;\n}\n\nfunction getTypeName(obj) {\n if (!obj || !obj.elements) {\n return '';\n }\n const type = obj.elements.filter(child => child && child.name && child.name.value === 'type');\n\n if (!type.length) {\n return '';\n }\n\n return (type[0].value && `:${type[0].value.value}`) || '';\n}\n","import { codeFrameColumns } from '@babel/code-frame';\nimport { getMetaFromPath, getDecoratedDataPath } from '../json/index';\n\nexport default class BaseValidationError {\n constructor(options = { isIdentifierLocation: false }, { data, schema, jsonAst, jsonRaw }) {\n this.options = options;\n this.data = data;\n this.schema = schema;\n this.jsonAst = jsonAst;\n this.jsonRaw = jsonRaw;\n }\n\n getLocation(dataPath = this.instancePath) {\n const { isIdentifierLocation, isSkipEndLocation } = this.options;\n const { loc } = getMetaFromPath(this.jsonAst, dataPath, isIdentifierLocation);\n return {\n start: loc.start,\n end: isSkipEndLocation ? undefined : loc.end,\n };\n }\n\n getDecoratedPath(dataPath = this.instancePath) {\n const decoratedPath = getDecoratedDataPath(this.jsonAst, dataPath);\n return decoratedPath;\n }\n\n // The decorated path is empty at the root, where the message stands alone.\n withDecoratedPath(message, separator = ' ') {\n const decoratedPath = this.getDecoratedPath();\n return decoratedPath ? `${decoratedPath}${separator}${message}` : message;\n }\n\n getCodeFrame(message, dataPath = this.instancePath) {\n return codeFrameColumns(this.jsonRaw, this.getLocation(dataPath), {\n highlightCode: true,\n message,\n });\n }\n\n /**\n * @return {string}\n */\n get instancePath() {\n return typeof this.options.instancePath !== 'undefined'\n ? this.options.instancePath\n : this.options.dataPath;\n }\n\n print() {\n throw new Error(`Implement the 'print' method inside ${this.constructor.name}!`);\n }\n\n getError() {\n throw new Error(`Implement the 'getError' method inside ${this.constructor.name}!`);\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class RequiredValidationError extends BaseValidationError {\n getLocation(dataPath = this.instancePath) {\n const { start } = super.getLocation(dataPath);\n return { start };\n }\n\n print() {\n const { message, params } = this.options;\n const output = [styleText('red', styleText('bold', 'REQUIRED') + ' ' + message) + '\\n'];\n\n return output.concat(\n this.getCodeFrame(\n '☹️ ' + styleText('magentaBright', params.missingProperty) + ' is missing here!'\n )\n );\n }\n\n getError() {\n const { message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(message),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class AdditionalPropValidationError extends BaseValidationError {\n constructor(...args) {\n super(...args);\n this.options.isIdentifierLocation = true;\n }\n\n print() {\n const { message, params } = this.options;\n const output = [\n styleText('red', styleText('bold', 'ADDITIONAL PROPERTY') + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame(\n '😲 ' +\n styleText('magentaBright', params.additionalProperty) +\n ' is not expected to be here!',\n `${this.instancePath}/${params.additionalProperty}`\n )\n );\n }\n\n getError() {\n const { params } = this.options;\n\n return {\n ...this.getLocation(`${this.instancePath}/${params.additionalProperty}`),\n error: this.withDecoratedPath(\n `Property ${params.additionalProperty} is not expected to be here`\n ),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport leven from 'leven';\nimport pointer from 'jsonpointer';\nimport BaseValidationError from './base';\n\nexport default class EnumValidationError extends BaseValidationError {\n print() {\n const {\n message,\n params: { allowedValues },\n } = this.options;\n const bestMatch = this.findBestMatch();\n\n // Needed to handle nullable enums, as joining on null just prints \", \"\n const [firstValue, ...rest] = allowedValues;\n const allowedValuesMessage = rest.reduce((acc, value) => `${acc}, ${value}`, firstValue || '');\n\n const output = [\n styleText('red', styleText('bold', 'ENUM') + ' ' + message),\n styleText('red', `(${allowedValuesMessage})\\n`),\n ];\n\n return output.concat(\n this.getCodeFrame(\n bestMatch !== null\n ? '👈🏽 Did you mean ' + styleText('magentaBright', String(bestMatch)) + ' here?'\n : '👈🏽 Unexpected value, should be equal to one of the allowed values'\n )\n );\n }\n\n getError() {\n const { message, params } = this.options;\n const bestMatch = this.findBestMatch();\n const allowedValues = params.allowedValues.join(', ');\n\n const output = {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${message}: ${allowedValues}`),\n path: this.instancePath,\n };\n\n if (bestMatch !== null) {\n output.suggestion = `Did you mean ${bestMatch}?`;\n }\n\n return output;\n }\n\n findBestMatch() {\n const {\n params: { allowedValues },\n } = this.options;\n\n const currentValue =\n this.instancePath === '' ? this.data : pointer.get(this.data, this.instancePath);\n\n if (!currentValue) {\n return null;\n }\n\n const bestMatch = allowedValues\n .map(value => ({\n value,\n // leven compares strings, so other allowed values cannot be a close match.\n weight: typeof value === 'string' ? leven(value, currentValue.toString()) : Infinity,\n }))\n .sort((x, y) => (x.weight > y.weight ? 1 : x.weight < y.weight ? -1 : 0))[0];\n\n return allowedValues.length === 1 || bestMatch.weight < bestMatch.value.length\n ? bestMatch.value\n : null;\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class DefaultValidationError extends BaseValidationError {\n print() {\n const { keyword, message } = this.options;\n const output = [\n styleText('red', styleText('bold', keyword.toUpperCase()) + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame('👈🏽 ' + styleText('magentaBright', keyword) + ' ' + message)\n );\n }\n\n getError() {\n const { keyword, message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${keyword} ${message}`, ': '),\n path: this.instancePath,\n };\n }\n}\n","import {\n getChildren,\n getErrors,\n getSiblings,\n isAnyOfError,\n isEnumError,\n isRequiredError,\n concatAll,\n notUndefined,\n} from './utils';\nimport {\n AdditionalPropValidationError,\n RequiredValidationError,\n EnumValidationError,\n DefaultValidationError,\n} from './validation-errors/index';\n\nconst JSON_POINTERS_REGEX = /\\/[\\w_-]+(\\/\\d+)?/g;\n\n// Make a tree of errors from ajv errors array\nexport function makeTree(ajvErrors = []) {\n const root = { children: {} };\n ajvErrors.forEach(ajvError => {\n const instancePath =\n typeof ajvError.instancePath !== 'undefined' ? ajvError.instancePath : ajvError.dataPath;\n\n // `dataPath === ''` is root\n const paths = instancePath === '' ? [''] : instancePath.match(JSON_POINTERS_REGEX);\n if (paths) {\n paths.reduce((obj, path, i) => {\n obj.children[path] = obj.children[path] || { children: {}, errors: [] };\n if (i === paths.length - 1) {\n obj.children[path].errors.push(ajvError);\n }\n return obj.children[path];\n }, root);\n }\n });\n return root;\n}\n\nexport function filterRedundantErrors(root, parent, key) {\n /**\n * Partition out the errors by kind for ease of proceessing\n */\n const { anyOfErrors, enumErrors, requiredErrors } = getErrors(root).reduce(\n (acc, error) => {\n if (isRequiredError(error)) {\n acc.requiredErrors.push(error);\n\n return acc;\n }\n\n if (isAnyOfError(error)) {\n acc.anyOfErrors.push(error);\n }\n\n if (isEnumError(error)) {\n acc.enumErrors.push(error);\n }\n\n return acc;\n },\n { anyOfErrors: [], enumErrors: [], requiredErrors: [] }\n );\n\n /**\n * If there is are `required` errors then we can just drop every non-required error.\n * And, also `required` should have more priority than `anyOf`. @see #8\n */\n\n if (requiredErrors.length > 0) {\n root.errors = requiredErrors;\n root.children = {};\n\n // No need for further processing, as we've emptied out children\n return;\n }\n\n /**\n * If there is an `anyOf` error that means we have more meaningful errors\n * inside children. So we will just remove all errors from this level.\n *\n * If there are no children, then we don't delete the errors since we should\n * have at least one error to report.\n */\n if (anyOfErrors.length > 0 && Object.keys(root.children).length > 0) {\n delete root.errors;\n }\n\n /**\n * If all errors are `enum` and siblings have any error then we can safely\n * ignore the node. As we return early if there's required errors, we only\n * need to check anyofErrors length\n *\n * **CAUTION**\n * Need explicit `root.errors` check because `[].every(fn) === true`\n * https://en.wikipedia.org/wiki/Vacuous_truth#Vacuous_truths_in_mathematics\n */\n if (enumErrors.length > 0 && anyOfErrors.length === 0) {\n if (\n getSiblings(parent)(root)\n // Remove any reference which becomes `undefined` later\n .filter(notUndefined)\n .some(getErrors)\n ) {\n delete parent.children[key];\n }\n }\n\n Object.entries(root.children).forEach(([key, child]) => filterRedundantErrors(child, root, key));\n}\n\nexport function createErrorInstances(root, options) {\n const errors = getErrors(root);\n if (errors.length && errors.every(isEnumError)) {\n const uniqueValues = new Set(concatAll([])(errors.map(e => e.params.allowedValues)));\n const allowedValues = [...uniqueValues];\n const error = errors[0];\n return [\n new EnumValidationError(\n {\n ...error,\n params: { allowedValues },\n },\n options\n ),\n ];\n } else {\n return concatAll(\n errors.reduce((ret, error) => {\n switch (error.keyword) {\n case 'additionalProperties':\n return ret.concat(new AdditionalPropValidationError(error, options));\n case 'required':\n return ret.concat(new RequiredValidationError(error, options));\n default:\n return ret.concat(new DefaultValidationError(error, options));\n }\n }, [])\n )(getChildren(root).map(child => createErrorInstances(child, options)));\n }\n}\n\nexport default (ajvErrors, options) => {\n const tree = makeTree(ajvErrors || []);\n filterRedundantErrors(tree);\n return createErrorInstances(tree, options);\n};\n","import { parse } from '@humanwhocodes/momoa';\nimport prettify from './helpers';\n\nexport default (schema, data, errors, options = {}) => {\n const { format = 'cli', indent = null, json = null } = options;\n\n const jsonRaw = json || JSON.stringify(data, null, indent);\n const jsonAst = parse(jsonRaw);\n\n const customErrorToText = error => error.print().join('\\n');\n const customErrorToStructure = error => error.getError();\n const customErrors = prettify(errors, {\n data,\n schema,\n jsonAst,\n jsonRaw,\n });\n\n if (format === 'cli') {\n return customErrors.map(customErrorToText).join('\\n\\n');\n } else {\n return customErrors.map(customErrorToStructure);\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["prettify"],"sources":["../src/utils.js","../src/code-frame.js","../src/json/utils.js","../src/json/get-meta-from-path.js","../src/json/get-decorated-data-path.js","../src/validation-errors/base.js","../src/validation-errors/required.js","../src/validation-errors/additional-prop.js","../src/validation-errors/enum.js","../src/validation-errors/default.js","../src/helpers.js","../src/index.js"],"sourcesContent":["// Basic\nconst eq = x => y => x === y;\nconst not = fn => x => !fn(x);\n\nconst getValues = o => Object.values(o);\n\nexport const notUndefined = x => x !== undefined;\n\n// Error\nconst isXError = x => error => error.keyword === x;\nexport const isRequiredError = isXError('required');\nexport const isAnyOfError = isXError('anyOf');\nexport const isEnumError = isXError('enum');\nexport const getErrors = node =>\n node && node.errors\n ? node.errors.map(e =>\n e.keyword === 'errorMessage' ? { ...e.params.errors[0], message: e.message } : e\n )\n : [];\n\n// Node\nexport const getChildren = node => (node && getValues(node.children)) || [];\n\nexport const getSiblings = parent => node => getChildren(parent).filter(not(eq(node)));\n\nexport const concatAll = xs => ys => ys.reduce((zs, z) => zs.concat(z), xs);\n","import { styleText } from 'node:util';\nimport { tokenize } from '@humanwhocodes/momoa';\n\nconst LINES_ABOVE = 2;\nconst LINES_BELOW = 3;\n\n// The line breaks momoa counts, so that its line numbers index into the split source.\nconst NEWLINE = /\\r\\n|[\\r\\n]/;\n\nconst TOKEN_STYLES = {\n String: 'green',\n Number: 'magenta',\n Boolean: 'cyan',\n Null: 'cyan',\n Colon: 'yellow',\n Comma: 'yellow',\n};\n\nconst MARKER_STYLE = ['red', 'bold'];\n\n// The check `styleText` makes for the headings, so that the frame is colored along with them.\nconst supportsColor = () => styleText('red', '-') !== '-';\n\n/**\n * Renders the lines of `source` around `location`, with carets under the located text and\n * `message` after the last caret.\n *\n * Lines and columns are 1-based and `end` is exclusive, as in momoa's locations. Without\n * `end`, a single caret marks `start`.\n *\n * @param {string} source\n * @param {{ start: { line: number, column: number }, end?: { line: number, column: number } }} location\n * @param {{ message?: string, color?: boolean }} [options]\n * @return {string}\n */\nexport default function codeFrame(\n source,\n { start, end = start },\n { message, color = supportsColor() } = {}\n) {\n const paint = color\n ? (format, text) => styleText(format, text, { validateStream: false })\n : (_format, text) => text;\n\n const lines = source.split(NEWLINE);\n const markers = getMarkers(lines, start, end);\n const first = Math.max(start.line - LINES_ABOVE, 1);\n const last = Math.min(end.line + LINES_BELOW, lines.length);\n const width = String(last).length;\n\n const rows = [];\n for (let number = first; number <= last; number++) {\n const line = lines[number - 1];\n const gutter = ` ${String(number).padStart(width)} |`;\n const code = line.length > 0 ? ` ${color ? highlight(line, paint) : line}` : '';\n const marker = markers.get(number);\n if (!marker) {\n rows.push(` ${paint('gray', gutter)}${code}`);\n continue;\n }\n\n const [column, count] = marker;\n const spacing = line.slice(0, column - 1).replace(/[^\\t]/g, ' ');\n let caretRow = ` ${paint('gray', gutter.replace(/\\d/g, ' '))} ${spacing}${paint(MARKER_STYLE, '^'.repeat(count))}`;\n if (message && number === end.line) {\n caretRow += ` ${paint(MARKER_STYLE, message)}`;\n }\n rows.push(`${paint(MARKER_STYLE, '>')}${paint('gray', gutter)}${code}`, caretRow);\n }\n\n return rows.join('\\n');\n}\n\n// Maps each marked line number to the column of its first caret and the number of carets.\nfunction getMarkers(lines, start, end) {\n const markers = new Map();\n if (start.line === end.line) {\n markers.set(start.line, [start.column, Math.max(end.column - start.column, 1)]);\n return markers;\n }\n\n markers.set(start.line, [start.column, lines[start.line - 1].length - start.column + 1]);\n for (let number = start.line + 1; number < end.line; number++) {\n markers.set(number, [1, Math.max(lines[number - 1].length, 1)]);\n }\n markers.set(end.line, [1, end.column - 1]);\n return markers;\n}\n\n// JSON strings can't contain raw line breaks, so each line holds whole tokens.\nfunction highlight(line, paint) {\n let output = '';\n let offset = 0;\n for (const { type, loc } of tokenize(line)) {\n const style = TOKEN_STYLES[type];\n if (style) {\n output +=\n line.slice(offset, loc.start.offset) +\n paint(style, line.slice(loc.start.offset, loc.end.offset));\n offset = loc.end.offset;\n }\n }\n return output + line.slice(offset);\n}\n","// TODO: Better error handling\nexport const getPointers = dataPath => {\n return dataPath\n .split('/')\n .slice(1)\n .map(pointer => pointer.split('~1').join('/').split('~0').join('~'));\n};\n","import { getPointers } from './utils';\n\nexport default function getMetaFromPath(jsonAst, dataPath, includeIdentifierLocation) {\n const pointers = getPointers(dataPath);\n const lastPointerIndex = pointers.length - 1;\n return pointers.reduce((obj, pointer, idx) => {\n switch (obj.type) {\n case 'Object': {\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n\n const { name, value } = member;\n return includeIdentifierLocation && idx === lastPointerIndex ? name : value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n return element && element.value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n}\n","import { getPointers } from './utils';\n\nexport default function getDecoratedDataPath(jsonAst, dataPath) {\n let decoratedPath = '';\n getPointers(dataPath).reduce((obj, pointer) => {\n switch (obj.type) {\n case 'Object': {\n decoratedPath += `/${pointer}`;\n // JSON.parse keeps the last of duplicate keys, so that is the one ajv validated.\n const member = obj.members.findLast(child => child.name.value === pointer);\n if (!member) {\n throw new Error(`Couldn't find property ${pointer} of ${dataPath}`);\n }\n return member.value;\n }\n case 'Array': {\n const element = obj.elements[pointer];\n const value = element && element.value;\n decoratedPath += `/${pointer}${getTypeName(value)}`;\n return value;\n }\n default:\n console.log(obj);\n }\n }, jsonAst.body);\n return decoratedPath;\n}\n\nfunction getTypeName(obj) {\n if (!obj || !obj.elements) {\n return '';\n }\n const type = obj.elements.filter(child => child && child.name && child.name.value === 'type');\n\n if (!type.length) {\n return '';\n }\n\n return (type[0].value && `:${type[0].value.value}`) || '';\n}\n","import codeFrame from '../code-frame';\nimport { getMetaFromPath, getDecoratedDataPath } from '../json/index';\n\nexport default class BaseValidationError {\n constructor(options = { isIdentifierLocation: false }, { data, schema, jsonAst, jsonRaw }) {\n this.options = options;\n this.data = data;\n this.schema = schema;\n this.jsonAst = jsonAst;\n this.jsonRaw = jsonRaw;\n }\n\n getLocation(dataPath = this.instancePath) {\n const { isIdentifierLocation, isSkipEndLocation } = this.options;\n const { loc } = getMetaFromPath(this.jsonAst, dataPath, isIdentifierLocation);\n return {\n start: loc.start,\n end: isSkipEndLocation ? undefined : loc.end,\n };\n }\n\n getDecoratedPath(dataPath = this.instancePath) {\n const decoratedPath = getDecoratedDataPath(this.jsonAst, dataPath);\n return decoratedPath;\n }\n\n // The decorated path is empty at the root, where the message stands alone.\n withDecoratedPath(message, separator = ' ') {\n const decoratedPath = this.getDecoratedPath();\n return decoratedPath ? `${decoratedPath}${separator}${message}` : message;\n }\n\n getCodeFrame(message, dataPath = this.instancePath) {\n return codeFrame(this.jsonRaw, this.getLocation(dataPath), { message });\n }\n\n /**\n * @return {string}\n */\n get instancePath() {\n return typeof this.options.instancePath !== 'undefined'\n ? this.options.instancePath\n : this.options.dataPath;\n }\n\n print() {\n throw new Error(`Implement the 'print' method inside ${this.constructor.name}!`);\n }\n\n getError() {\n throw new Error(`Implement the 'getError' method inside ${this.constructor.name}!`);\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class RequiredValidationError extends BaseValidationError {\n getLocation(dataPath = this.instancePath) {\n const { start } = super.getLocation(dataPath);\n return { start };\n }\n\n print() {\n const { message, params } = this.options;\n const output = [styleText('red', styleText('bold', 'REQUIRED') + ' ' + message) + '\\n'];\n\n return output.concat(\n this.getCodeFrame(\n '☹️ ' + styleText('magentaBright', params.missingProperty) + ' is missing here!'\n )\n );\n }\n\n getError() {\n const { message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(message),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class AdditionalPropValidationError extends BaseValidationError {\n constructor(...args) {\n super(...args);\n this.options.isIdentifierLocation = true;\n }\n\n print() {\n const { message, params } = this.options;\n const output = [\n styleText('red', styleText('bold', 'ADDITIONAL PROPERTY') + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame(\n '😲 ' +\n styleText('magentaBright', params.additionalProperty) +\n ' is not expected to be here!',\n `${this.instancePath}/${params.additionalProperty}`\n )\n );\n }\n\n getError() {\n const { params } = this.options;\n\n return {\n ...this.getLocation(`${this.instancePath}/${params.additionalProperty}`),\n error: this.withDecoratedPath(\n `Property ${params.additionalProperty} is not expected to be here`\n ),\n path: this.instancePath,\n };\n }\n}\n","import { styleText } from 'node:util';\nimport leven from 'leven';\nimport pointer from 'jsonpointer';\nimport BaseValidationError from './base';\n\nexport default class EnumValidationError extends BaseValidationError {\n print() {\n const {\n message,\n params: { allowedValues },\n } = this.options;\n const bestMatch = this.findBestMatch();\n\n // Needed to handle nullable enums, as joining on null just prints \", \"\n const [firstValue, ...rest] = allowedValues;\n const allowedValuesMessage = rest.reduce((acc, value) => `${acc}, ${value}`, firstValue || '');\n\n const output = [\n styleText('red', styleText('bold', 'ENUM') + ' ' + message),\n styleText('red', `(${allowedValuesMessage})\\n`),\n ];\n\n return output.concat(\n this.getCodeFrame(\n bestMatch !== null\n ? '👈🏽 Did you mean ' + styleText('magentaBright', String(bestMatch)) + ' here?'\n : '👈🏽 Unexpected value, should be equal to one of the allowed values'\n )\n );\n }\n\n getError() {\n const { message, params } = this.options;\n const bestMatch = this.findBestMatch();\n const allowedValues = params.allowedValues.join(', ');\n\n const output = {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${message}: ${allowedValues}`),\n path: this.instancePath,\n };\n\n if (bestMatch !== null) {\n output.suggestion = `Did you mean ${bestMatch}?`;\n }\n\n return output;\n }\n\n findBestMatch() {\n const {\n params: { allowedValues },\n } = this.options;\n\n const currentValue =\n this.instancePath === '' ? this.data : pointer.get(this.data, this.instancePath);\n\n if (!currentValue) {\n return null;\n }\n\n const bestMatch = allowedValues\n .map(value => ({\n value,\n // leven compares strings, so other allowed values cannot be a close match.\n weight: typeof value === 'string' ? leven(value, currentValue.toString()) : Infinity,\n }))\n .sort((x, y) => (x.weight > y.weight ? 1 : x.weight < y.weight ? -1 : 0))[0];\n\n return allowedValues.length === 1 || bestMatch.weight < bestMatch.value.length\n ? bestMatch.value\n : null;\n }\n}\n","import { styleText } from 'node:util';\nimport BaseValidationError from './base';\n\nexport default class DefaultValidationError extends BaseValidationError {\n print() {\n const { keyword, message } = this.options;\n const output = [\n styleText('red', styleText('bold', keyword.toUpperCase()) + ' ' + message) + '\\n',\n ];\n\n return output.concat(\n this.getCodeFrame('👈🏽 ' + styleText('magentaBright', keyword) + ' ' + message)\n );\n }\n\n getError() {\n const { keyword, message } = this.options;\n\n return {\n ...this.getLocation(),\n error: this.withDecoratedPath(`${keyword} ${message}`, ': '),\n path: this.instancePath,\n };\n }\n}\n","import {\n getChildren,\n getErrors,\n getSiblings,\n isAnyOfError,\n isEnumError,\n isRequiredError,\n concatAll,\n notUndefined,\n} from './utils';\nimport {\n AdditionalPropValidationError,\n RequiredValidationError,\n EnumValidationError,\n DefaultValidationError,\n} from './validation-errors/index';\n\nconst JSON_POINTERS_REGEX = /\\/[\\w_-]+(\\/\\d+)?/g;\n\n// Make a tree of errors from ajv errors array\nexport function makeTree(ajvErrors = []) {\n const root = { children: {} };\n ajvErrors.forEach(ajvError => {\n const instancePath =\n typeof ajvError.instancePath !== 'undefined' ? ajvError.instancePath : ajvError.dataPath;\n\n // `dataPath === ''` is root\n const paths = instancePath === '' ? [''] : instancePath.match(JSON_POINTERS_REGEX);\n if (paths) {\n paths.reduce((obj, path, i) => {\n obj.children[path] = obj.children[path] || { children: {}, errors: [] };\n if (i === paths.length - 1) {\n obj.children[path].errors.push(ajvError);\n }\n return obj.children[path];\n }, root);\n }\n });\n return root;\n}\n\nexport function filterRedundantErrors(root, parent, key) {\n /**\n * Partition out the errors by kind for ease of proceessing\n */\n const { anyOfErrors, enumErrors, requiredErrors } = getErrors(root).reduce(\n (acc, error) => {\n if (isRequiredError(error)) {\n acc.requiredErrors.push(error);\n\n return acc;\n }\n\n if (isAnyOfError(error)) {\n acc.anyOfErrors.push(error);\n }\n\n if (isEnumError(error)) {\n acc.enumErrors.push(error);\n }\n\n return acc;\n },\n { anyOfErrors: [], enumErrors: [], requiredErrors: [] }\n );\n\n /**\n * If there is are `required` errors then we can just drop every non-required error.\n * And, also `required` should have more priority than `anyOf`. @see #8\n */\n\n if (requiredErrors.length > 0) {\n root.errors = requiredErrors;\n root.children = {};\n\n // No need for further processing, as we've emptied out children\n return;\n }\n\n /**\n * If there is an `anyOf` error that means we have more meaningful errors\n * inside children. So we will just remove all errors from this level.\n *\n * If there are no children, then we don't delete the errors since we should\n * have at least one error to report.\n */\n if (anyOfErrors.length > 0 && Object.keys(root.children).length > 0) {\n delete root.errors;\n }\n\n /**\n * If all errors are `enum` and siblings have any error then we can safely\n * ignore the node. As we return early if there's required errors, we only\n * need to check anyofErrors length\n *\n * **CAUTION**\n * Need explicit `root.errors` check because `[].every(fn) === true`\n * https://en.wikipedia.org/wiki/Vacuous_truth#Vacuous_truths_in_mathematics\n */\n if (enumErrors.length > 0 && anyOfErrors.length === 0) {\n if (\n getSiblings(parent)(root)\n // Remove any reference which becomes `undefined` later\n .filter(notUndefined)\n .some(getErrors)\n ) {\n delete parent.children[key];\n }\n }\n\n Object.entries(root.children).forEach(([key, child]) => filterRedundantErrors(child, root, key));\n}\n\nexport function createErrorInstances(root, options) {\n const errors = getErrors(root);\n if (errors.length && errors.every(isEnumError)) {\n const uniqueValues = new Set(concatAll([])(errors.map(e => e.params.allowedValues)));\n const allowedValues = [...uniqueValues];\n const error = errors[0];\n return [\n new EnumValidationError(\n {\n ...error,\n params: { allowedValues },\n },\n options\n ),\n ];\n } else {\n return concatAll(\n errors.reduce((ret, error) => {\n switch (error.keyword) {\n case 'additionalProperties':\n return ret.concat(new AdditionalPropValidationError(error, options));\n case 'required':\n return ret.concat(new RequiredValidationError(error, options));\n default:\n return ret.concat(new DefaultValidationError(error, options));\n }\n }, [])\n )(getChildren(root).map(child => createErrorInstances(child, options)));\n }\n}\n\nexport default (ajvErrors, options) => {\n const tree = makeTree(ajvErrors || []);\n filterRedundantErrors(tree);\n return createErrorInstances(tree, options);\n};\n","import { parse } from '@humanwhocodes/momoa';\nimport prettify from './helpers';\n\nexport default (schema, data, errors, options = {}) => {\n const { format = 'cli', indent = null, json = null } = options;\n\n const jsonRaw = json || JSON.stringify(data, null, indent);\n const jsonAst = parse(jsonRaw);\n\n const customErrorToText = error => error.print().join('\\n');\n const customErrorToStructure = error => error.getError();\n const customErrors = prettify(errors, {\n data,\n schema,\n jsonAst,\n jsonRaw,\n });\n\n if (format === 'cli') {\n return customErrors.map(customErrorToText).join('\\n\\n');\n } else {\n return customErrors.map(customErrorToStructure);\n }\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "@atlassian/better-ajv-errors",
3
- "version": "3.0.0",
3
+ "version": "3.0.1",
4
4
  "description": "JSON Schema validation for Human",
5
- "repository": "atlassian/better-ajv-errors",
5
+ "repository": {
6
+ "type": "git",
7
+ "url": "git+https://github.com/atlassian/better-ajv-errors.git"
8
+ },
6
9
  "main": "./dist/index.cjs",
7
10
  "types": "./typings.d.cts",
8
11
  "type": "module",
@@ -21,7 +24,7 @@
21
24
  "engines": {
22
25
  "node": ">= 22"
23
26
  },
24
- "packageManager": "pnpm@10.34.6",
27
+ "packageManager": "pnpm@12.11.2",
25
28
  "keywords": [
26
29
  "json-schema",
27
30
  "ajv",
@@ -42,27 +45,25 @@
42
45
  "scripts": {
43
46
  "build": "vp pack",
44
47
  "prerelease": "npm run build",
45
- "release": "changeset publish",
48
+ "release": "pnpm publish",
46
49
  "release:atlassian": "node publish-atlassian.js",
47
- "format": "vp fmt './src/**/*.js' './.changeset/*.json'",
48
- "format:check": "vp fmt --check './src/**/*.js' './.changeset/*.json'",
50
+ "format": "vp fmt './src/**/*.js'",
51
+ "format:check": "vp fmt --check './src/**/*.js'",
49
52
  "prelint": "npm run build",
50
53
  "lint": "vp lint && publint",
51
54
  "lint:actions": "actionlint && zizmor .github/workflows",
52
55
  "test": "vp test",
53
56
  "test-ci": "vp test --coverage",
54
57
  "prescreenshot": "npm run build",
55
- "screenshot": "svg-term --command='node screenshot' --out=./media/screenshot.svg --padding=5 --width=80 --height=13 --at=1000 --no-cursor --term iterm2 --profile='deep' --window",
58
+ "screenshot": "FORCE_COLOR=1 node screenshot | svg-term --out=./media/screenshot.svg --padding=5 --width=80 --height=13 --at=1000 --no-cursor --term xresources --profile=./media/deep.Xresources --window",
56
59
  "prepare": "is-ci || vp config"
57
60
  },
58
61
  "dependencies": {
59
- "@babel/code-frame": "^7.29.7",
60
62
  "@humanwhocodes/momoa": "^3.3.13",
61
63
  "jsonpointer": "^5.0.1",
62
64
  "leven": "^3.1.0 < 4"
63
65
  },
64
66
  "devDependencies": {
65
- "@changesets/cli": "^3.0.3",
66
67
  "@vitest/coverage-v8": "catalog:",
67
68
  "@vitest/ui": "catalog:",
68
69
  "ajv": "^8.20.0",