html-validate 11.0.0 → 11.2.0

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.
Files changed (63) hide show
  1. package/dist/cjs/cli.js +8 -3
  2. package/dist/cjs/cli.js.map +1 -1
  3. package/dist/cjs/core.js +7 -4
  4. package/dist/cjs/core.js.map +1 -1
  5. package/dist/cjs/html-validate.js +35 -50
  6. package/dist/cjs/html-validate.js.map +1 -1
  7. package/dist/cjs/index.js +1 -1
  8. package/dist/cjs/{matchers.js → jest-matchers.js} +66 -38
  9. package/dist/cjs/jest-matchers.js.map +1 -0
  10. package/dist/cjs/{matcher-utils.js → jest-utils.js} +1 -8
  11. package/dist/cjs/jest-utils.js.map +1 -0
  12. package/dist/cjs/jest-worker.js.map +1 -1
  13. package/dist/cjs/jest.js +10 -13
  14. package/dist/cjs/jest.js.map +1 -1
  15. package/dist/cjs/vitest-matchers.js +281 -0
  16. package/dist/cjs/vitest-matchers.js.map +1 -0
  17. package/dist/cjs/vitest-utils.js +120 -0
  18. package/dist/cjs/vitest-utils.js.map +1 -0
  19. package/dist/cjs/vitest-worker.d.ts +1 -0
  20. package/dist/cjs/vitest-worker.js +63 -0
  21. package/dist/cjs/vitest-worker.js.map +1 -0
  22. package/dist/cjs/vitest.js +9 -7
  23. package/dist/cjs/vitest.js.map +1 -1
  24. package/dist/esm/browser.js +1 -1
  25. package/dist/esm/cli.js +10 -5
  26. package/dist/esm/cli.js.map +1 -1
  27. package/dist/esm/core-browser.js +1 -1
  28. package/dist/esm/core-nodejs.js +1 -1
  29. package/dist/esm/core.js +6 -4
  30. package/dist/esm/core.js.map +1 -1
  31. package/dist/esm/html-validate.js +37 -51
  32. package/dist/esm/html-validate.js.map +1 -1
  33. package/dist/esm/index.js +2 -2
  34. package/dist/esm/jest-matchers.js +263 -0
  35. package/dist/esm/jest-matchers.js.map +1 -0
  36. package/dist/esm/{matcher-utils.js → jest-utils.js} +3 -9
  37. package/dist/esm/jest-utils.js.map +1 -0
  38. package/dist/esm/jest-worker.js.map +1 -1
  39. package/dist/esm/jest.js +6 -9
  40. package/dist/esm/jest.js.map +1 -1
  41. package/dist/esm/{matchers.js → vitest-matchers.js} +62 -45
  42. package/dist/esm/vitest-matchers.js.map +1 -0
  43. package/dist/esm/vitest-utils.js +116 -0
  44. package/dist/esm/vitest-utils.js.map +1 -0
  45. package/dist/esm/vitest-worker.d.ts +1 -0
  46. package/dist/esm/vitest-worker.js +62 -0
  47. package/dist/esm/vitest-worker.js.map +1 -0
  48. package/dist/esm/vitest.js +9 -7
  49. package/dist/esm/vitest.js.map +1 -1
  50. package/dist/types/vitest.d.ts +18 -0
  51. package/package.json +7 -9
  52. package/dist/cjs/jest-diff.js +0 -41
  53. package/dist/cjs/jest-diff.js.map +0 -1
  54. package/dist/cjs/matcher-utils.js.map +0 -1
  55. package/dist/cjs/matchers-jestonly.js +0 -44
  56. package/dist/cjs/matchers-jestonly.js.map +0 -1
  57. package/dist/cjs/matchers.js.map +0 -1
  58. package/dist/esm/jest-diff.js +0 -20
  59. package/dist/esm/jest-diff.js.map +0 -1
  60. package/dist/esm/matcher-utils.js.map +0 -1
  61. package/dist/esm/matchers-jestonly.js +0 -41
  62. package/dist/esm/matchers-jestonly.js.map +0 -1
  63. package/dist/esm/matchers.js.map +0 -1
@@ -0,0 +1,281 @@
1
+ 'use strict';
2
+
3
+ var vitestUtils = require('./vitest-utils.js');
4
+ var core = require('./core.js');
5
+ var vitest = require('vitest');
6
+ var coreNodejs = require('./core-nodejs.js');
7
+
8
+ function _interopNamespace(e) {
9
+ if (e && e.__esModule) return e;
10
+ var n = Object.create(null);
11
+ if (e) {
12
+ Object.keys(e).forEach(function (k) {
13
+ if (k !== 'default') {
14
+ var d = Object.getOwnPropertyDescriptor(e, k);
15
+ Object.defineProperty(n, k, d.get ? d : {
16
+ enumerable: true,
17
+ get: function () { return e[k]; }
18
+ });
19
+ }
20
+ });
21
+ }
22
+ n.default = e;
23
+ return Object.freeze(n);
24
+ }
25
+
26
+ var vitest__namespace = /*#__PURE__*/_interopNamespace(vitest);
27
+
28
+ function createMatcher$6() {
29
+ function toBeValid(report) {
30
+ if (report.valid) {
31
+ return {
32
+ pass: true,
33
+ message: (
34
+ /* istanbul ignore next */
35
+ () => "Result should not contain error"
36
+ )
37
+ };
38
+ } else {
39
+ const firstError = report.results[0].messages[0];
40
+ return {
41
+ pass: false,
42
+ message: () => `Result should be valid but had error "${firstError.message}"`
43
+ };
44
+ }
45
+ }
46
+ return vitestUtils.diverge(toBeValid);
47
+ }
48
+
49
+ function createMatcher$5() {
50
+ function toBeInvalid(report) {
51
+ if (report.valid) {
52
+ return {
53
+ pass: false,
54
+ message: () => "Result should be invalid but had no errors"
55
+ };
56
+ } else {
57
+ return {
58
+ pass: true,
59
+ message: (
60
+ /* istanbul ignore next */
61
+ () => "Result should not contain error"
62
+ )
63
+ };
64
+ }
65
+ }
66
+ return vitestUtils.diverge(toBeInvalid);
67
+ }
68
+
69
+ function isMessage(arg) {
70
+ if (!arg || typeof arg !== "object") {
71
+ return false;
72
+ }
73
+ return [
74
+ "ruleId",
75
+ "severity",
76
+ "message",
77
+ "offset",
78
+ "line",
79
+ "column",
80
+ "size",
81
+ "selector",
82
+ "context"
83
+ ].some((key) => key in arg);
84
+ }
85
+ function isConfig(arg) {
86
+ if (!arg || typeof arg !== "object") {
87
+ return false;
88
+ }
89
+ return ["root", "extends", "elements", "plugin", "transform", "rules"].some((key) => key in arg);
90
+ }
91
+ function isString(arg) {
92
+ return typeof arg === "string";
93
+ }
94
+ function getMarkup(src) {
95
+ if (typeof HTMLElement !== "undefined" && src instanceof HTMLElement) {
96
+ return src.outerHTML;
97
+ }
98
+ if (typeof src === "string") {
99
+ return src;
100
+ } else {
101
+ throw new TypeError(`Failed to get markup from "${typeof src}" argument`);
102
+ }
103
+ }
104
+ function createMatcher$4(expect) {
105
+ function toHTMLValidate(actual, arg0, arg1, arg2) {
106
+ const markup = getMarkup(actual);
107
+ const message = isMessage(arg0) ? arg0 : void 0;
108
+ const config = isConfig(arg0) ? arg0 : isConfig(arg1) ? arg1 : void 0;
109
+ const filename = isString(arg0) ? arg0 : isString(arg1) ? arg1 : arg2;
110
+ return toHTMLValidateImpl.call(this, expect, markup, message, config, filename);
111
+ }
112
+ return vitestUtils.diverge(toHTMLValidate);
113
+ }
114
+ function toHTMLValidateImpl(expect, actual, expectedError, userConfig, filename) {
115
+ const defaultConfig = {
116
+ rules: {
117
+ /* jsdom normalizes style so disabling rule when using this matcher or it
118
+ * gets quite noisy when configured with self-closing */
119
+ "void-style": "off"
120
+ }
121
+ };
122
+ const config = core.deepmerge(defaultConfig, userConfig ?? {});
123
+ const actualFilename = filename ?? this.testPath ?? "inline";
124
+ const syncFn = vitestUtils.createSyncFn(core.vitestWorkerPath);
125
+ const report = syncFn(actual, actualFilename, config);
126
+ const pass = report.valid;
127
+ const result = report.results[0];
128
+ if (pass) {
129
+ return { pass, message: () => "HTML is valid when an error was expected" };
130
+ } else {
131
+ if (expectedError) {
132
+ const actual2 = result.messages;
133
+ const expected = expect.arrayContaining([expect.objectContaining(expectedError)]);
134
+ const errorPass = this.equals(actual2, expected);
135
+ const diffString = this.utils.diff(expected, actual2, {
136
+ aAnnotation: "Expected error",
137
+ bAnnotation: "Actual error"
138
+ });
139
+ const hint = this.utils.matcherHint(".not.toHTMLValidate", void 0, void 0, {
140
+ comment: "expected error"
141
+ });
142
+ const expectedErrorMessage = () => [
143
+ hint,
144
+ "",
145
+ "Expected error to be present:",
146
+ this.utils.printExpected(expectedError),
147
+ /* istanbul ignore next */
148
+ diffString ? `
149
+ ${diffString}` : ""
150
+ ].join("\n");
151
+ return { pass: !errorPass, message: expectedErrorMessage, actual: actual2, expected };
152
+ }
153
+ const errors = result.messages.map((message) => ` ${message.message} [${message.ruleId}]`);
154
+ return {
155
+ pass,
156
+ message: () => ["Expected HTML to be valid but had the following errors:", ""].concat(errors).join("\n")
157
+ };
158
+ }
159
+ }
160
+
161
+ function toHaveErrorImpl(context, expect, actual, expected) {
162
+ const flattened = actual.results.flatMap((result) => result.messages);
163
+ const matcher = [expect.objectContaining(expected)];
164
+ const pass = context.equals(flattened, matcher);
165
+ const diffString = context.utils.diff(matcher, flattened);
166
+ const hint = context.utils.matcherHint(".toHaveError");
167
+ const prettyExpected = context.utils.printExpected(matcher);
168
+ const prettyReceived = context.utils.printReceived(flattened);
169
+ const resultMessage = () => {
170
+ return [
171
+ hint,
172
+ "",
173
+ "Expected error to equal:",
174
+ ` ${prettyExpected}`,
175
+ "Received:",
176
+ ` ${prettyReceived}`,
177
+ /* istanbul ignore next */
178
+ diffString ? `
179
+ Difference:
180
+
181
+ ${diffString}` : ""
182
+ ].join("\n");
183
+ };
184
+ return { pass, message: resultMessage, actual: flattened, expected: matcher };
185
+ }
186
+ function createMatcher$3(expect) {
187
+ function toHaveError(actual, arg1, arg2, arg3) {
188
+ if (typeof arg1 === "string") {
189
+ const expected = {
190
+ ruleId: arg1,
191
+ message: arg2
192
+ };
193
+ if (arg3 !== void 0) {
194
+ expected.context = arg3;
195
+ }
196
+ return toHaveErrorImpl(this, expect, actual, expected);
197
+ } else {
198
+ return toHaveErrorImpl(this, expect, actual, arg1);
199
+ }
200
+ }
201
+ return vitestUtils.diverge(toHaveError);
202
+ }
203
+
204
+ function createMatcher$2(expect) {
205
+ function toHaveErrors(report, errors) {
206
+ const flattened = report.results.flatMap((result) => result.messages);
207
+ const matcher = errors.map((entry) => {
208
+ if (Array.isArray(entry)) {
209
+ const [ruleId, message] = entry;
210
+ return expect.objectContaining({ ruleId, message });
211
+ } else {
212
+ return expect.objectContaining(entry);
213
+ }
214
+ });
215
+ const pass = this.equals(flattened, matcher);
216
+ const diffString = this.utils.diff(matcher, flattened);
217
+ const resultMessage = () => this.utils.matcherHint(".toHaveErrors") + `
218
+
219
+ Expected error to equal:
220
+ ${this.utils.printExpected(matcher)}
221
+ Received:
222
+ ${this.utils.printReceived(flattened)}` + /* istanbul ignore next */
223
+ (diffString ? `
224
+
225
+ Difference:
226
+
227
+ ${diffString}` : "");
228
+ return { pass, message: resultMessage };
229
+ }
230
+ return vitestUtils.diverge(toHaveErrors);
231
+ }
232
+
233
+ function createMatcher$1() {
234
+ const htmlvalidate = new coreNodejs.HtmlValidate();
235
+ async function toMatchCodeframe(received, hint) {
236
+ if (!vitest__namespace.Snapshots) {
237
+ throw new Error("toMatchCodeframe() requires vitest 4.1.3 or later. Please upgrade vitest.");
238
+ }
239
+ const resolved = await received;
240
+ let report;
241
+ if (typeof resolved === "string") {
242
+ report = await htmlvalidate.validateString(resolved);
243
+ } else {
244
+ report = resolved;
245
+ }
246
+ const snapshot = vitestUtils.codeframe(report.results).replaceAll(/\s+$/gm, "");
247
+ return vitest__namespace.Snapshots.toMatchSnapshot.call(this, snapshot, hint);
248
+ }
249
+ return toMatchCodeframe;
250
+ }
251
+
252
+ function createMatcher() {
253
+ const htmlvalidate = new coreNodejs.HtmlValidate();
254
+ async function toMatchInlineCodeframe(received, inlineSnapshot) {
255
+ if (!vitest__namespace.Snapshots) {
256
+ throw new Error(
257
+ "toMatchInlineCodeframe() requires vitest 4.1.3 or later. Please upgrade vitest."
258
+ );
259
+ }
260
+ vitest__namespace.chai.util.flag(this.assertion, "error", new Error("stacktrace"));
261
+ const resolved = await received;
262
+ let report;
263
+ if (typeof resolved === "string") {
264
+ report = await htmlvalidate.validateString(resolved);
265
+ } else {
266
+ report = resolved;
267
+ }
268
+ const snapshot = vitestUtils.codeframe(report.results).replaceAll(/\s+$/gm, "");
269
+ return vitest__namespace.Snapshots.toMatchInlineSnapshot.call(this, snapshot, inlineSnapshot);
270
+ }
271
+ return toMatchInlineCodeframe;
272
+ }
273
+
274
+ exports.createMatcher = createMatcher;
275
+ exports.createMatcher$1 = createMatcher$1;
276
+ exports.createMatcher$2 = createMatcher$2;
277
+ exports.createMatcher$3 = createMatcher$3;
278
+ exports.createMatcher$4 = createMatcher$4;
279
+ exports.createMatcher$5 = createMatcher$5;
280
+ exports.createMatcher$6 = createMatcher$6;
281
+ //# sourceMappingURL=vitest-matchers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-matchers.js","sources":["../../src/vitest/matchers/to-be-valid.ts","../../src/vitest/matchers/to-be-invalid.ts","../../src/vitest/matchers/to-htmlvalidate.ts","../../src/vitest/matchers/to-have-error.ts","../../src/vitest/matchers/to-have-errors.ts","../../src/vitest/matchers/to-match-codeframe.ts","../../src/vitest/matchers/to-match-inline-codeframe.ts"],"sourcesContent":["import { type SyncExpectationResult } from \"@vitest/expect\";\nimport { type Report } from \"../../reporter\";\nimport { type MaybeAsyncCallback, diverge } from \"../utils\";\n\nfunction createMatcher(): MaybeAsyncCallback<Report, []> {\n\tfunction toBeValid(report: Report): SyncExpectationResult {\n\t\tif (report.valid) {\n\t\t\treturn {\n\t\t\t\tpass: true,\n\t\t\t\tmessage: /* istanbul ignore next */ () => \"Result should not contain error\",\n\t\t\t};\n\t\t} else {\n\t\t\tconst firstError = report.results[0].messages[0];\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tmessage: () => `Result should be valid but had error \"${firstError.message}\"`,\n\t\t\t};\n\t\t}\n\t}\n\treturn diverge(toBeValid);\n}\n\nexport { createMatcher as toBeValid };\n","import { type SyncExpectationResult } from \"@vitest/expect\";\nimport { type Report } from \"../../reporter\";\nimport { type MaybeAsyncCallback, diverge } from \"../utils\";\n\nfunction createMatcher(): MaybeAsyncCallback<Report, []> {\n\tfunction toBeInvalid(report: Report): SyncExpectationResult {\n\t\tif (report.valid) {\n\t\t\treturn {\n\t\t\t\tpass: false,\n\t\t\t\tmessage: () => \"Result should be invalid but had no errors\",\n\t\t\t};\n\t\t} else {\n\t\t\treturn {\n\t\t\t\tpass: true,\n\t\t\t\tmessage: /* istanbul ignore next */ () => \"Result should not contain error\",\n\t\t\t};\n\t\t}\n\t}\n\treturn diverge(toBeInvalid);\n}\n\nexport { createMatcher as toBeInvalid };\n","import { type MatcherState, type SyncExpectationResult } from \"@vitest/expect\";\nimport deepmerge from \"deepmerge\";\nimport { type expect } from \"vitest\";\nimport { type ConfigData } from \"../../config\";\nimport { type Message } from \"../../message\";\nimport { type MaybeAsyncCallback, diverge } from \"../utils\";\nimport { type ValidateStringFn, createSyncFn, vitestWorkerPath } from \"../worker\";\n\ntype VitestExpect = typeof expect;\n\nfunction isMessage(arg: Arg1 | undefined): arg is Partial<Message> {\n\tif (!arg || typeof arg !== \"object\") {\n\t\treturn false;\n\t}\n\treturn [\n\t\t\"ruleId\",\n\t\t\"severity\",\n\t\t\"message\",\n\t\t\"offset\",\n\t\t\"line\",\n\t\t\"column\",\n\t\t\"size\",\n\t\t\"selector\",\n\t\t\"context\",\n\t].some((key) => key in arg);\n}\n\nfunction isConfig(arg: Arg1 | undefined): arg is ConfigData {\n\tif (!arg || typeof arg !== \"object\") {\n\t\treturn false;\n\t}\n\treturn [\"root\", \"extends\", \"elements\", \"plugin\", \"transform\", \"rules\"].some((key) => key in arg);\n}\n\nfunction isString(arg: Arg1 | undefined): arg is string {\n\treturn typeof arg === \"string\";\n}\n\nfunction getMarkup(src: unknown): string {\n\tif (typeof HTMLElement !== \"undefined\" && src instanceof HTMLElement) {\n\t\treturn (src as { outerHTML: string }).outerHTML;\n\t}\n\t/* istanbul ignore else: prototype only allows string or HTMLElement */\n\tif (typeof src === \"string\") {\n\t\treturn src;\n\t} else {\n\t\tthrow new TypeError(`Failed to get markup from \"${typeof src}\" argument`);\n\t}\n}\n\ntype Arg1 = Partial<Message> | ConfigData | string;\ntype Arg2 = ConfigData | string;\ntype Arg3 = string;\n\nfunction createMatcher(expect: VitestExpect): MaybeAsyncCallback<unknown, [Arg1?, Arg2?, Arg3?]> {\n\tfunction toHTMLValidate(\n\t\tthis: MatcherState,\n\t\tactual: unknown,\n\t\targ0?: Arg1,\n\t\targ1?: Arg2,\n\t\targ2?: Arg3,\n\t): SyncExpectationResult {\n\t\tconst markup = getMarkup(actual);\n\t\tconst message = isMessage(arg0) ? arg0 : undefined;\n\t\tconst config = isConfig(arg0) ? arg0 : isConfig(arg1) ? arg1 : undefined; // eslint-disable-line sonarjs/no-nested-conditional -- easier to read than the alternative */\n\t\tconst filename = isString(arg0) ? arg0 : isString(arg1) ? arg1 : arg2; // eslint-disable-line sonarjs/no-nested-conditional -- easier to read than the alternative */\n\t\treturn toHTMLValidateImpl.call(this, expect, markup, message, config, filename);\n\t}\n\treturn diverge(toHTMLValidate);\n}\n\n/* eslint-disable-next-line @typescript-eslint/max-params -- technical debt */\nfunction toHTMLValidateImpl(\n\tthis: MatcherState,\n\texpect: VitestExpect,\n\tactual: string,\n\texpectedError?: Partial<Message>,\n\tuserConfig?: ConfigData,\n\tfilename?: string,\n): SyncExpectationResult {\n\tconst defaultConfig = {\n\t\trules: {\n\t\t\t/* jsdom normalizes style so disabling rule when using this matcher or it\n\t\t\t * gets quite noisy when configured with self-closing */\n\t\t\t\"void-style\": \"off\",\n\t\t},\n\t};\n\tconst config = deepmerge(defaultConfig, userConfig ?? {});\n\t/* istanbul ignore next: cant figure out when this would be unset */\n\tconst actualFilename = filename ?? this.testPath ?? \"inline\";\n\n\tconst syncFn = createSyncFn<ValidateStringFn>(vitestWorkerPath);\n\tconst report = syncFn(actual, actualFilename, config);\n\tconst pass = report.valid;\n\tconst result = report.results[0];\n\tif (pass) {\n\t\treturn { pass, message: () => \"HTML is valid when an error was expected\" };\n\t} else {\n\t\tif (expectedError) {\n\t\t\tconst actual = result.messages;\n\t\t\t/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- upstream typing */\n\t\t\tconst expected = expect.arrayContaining([expect.objectContaining(expectedError)]);\n\t\t\tconst errorPass = this.equals(actual, expected);\n\t\t\tconst diffString = this.utils.diff(expected, actual, {\n\t\t\t\taAnnotation: \"Expected error\",\n\t\t\t\tbAnnotation: \"Actual error\",\n\t\t\t});\n\t\t\tconst hint = this.utils.matcherHint(\".not.toHTMLValidate\", undefined, undefined, {\n\t\t\t\tcomment: \"expected error\",\n\t\t\t});\n\t\t\tconst expectedErrorMessage = (): string =>\n\t\t\t\t[\n\t\t\t\t\thint,\n\t\t\t\t\t\"\",\n\t\t\t\t\t\"Expected error to be present:\",\n\t\t\t\t\tthis.utils.printExpected(expectedError),\n\t\t\t\t\t/* istanbul ignore next */ diffString ? `\\n${diffString}` : \"\",\n\t\t\t\t].join(\"\\n\");\n\t\t\t/* eslint-disable-next-line @typescript-eslint/no-unsafe-assignment -- upstream typing */\n\t\t\treturn { pass: !errorPass, message: expectedErrorMessage, actual, expected };\n\t\t}\n\n\t\tconst errors = result.messages.map((message) => ` ${message.message} [${message.ruleId}]`);\n\t\treturn {\n\t\t\tpass,\n\t\t\tmessage: () =>\n\t\t\t\t[\"Expected HTML to be valid but had the following errors:\", \"\"].concat(errors).join(\"\\n\"),\n\t\t};\n\t}\n}\n\nexport { createMatcher as toHTMLValidate };\n","import { type MatcherState, type SyncExpectationResult } from \"@vitest/expect\";\nimport { type expect } from \"vitest\";\nimport { type Message } from \"../../message\";\nimport { type Report } from \"../../reporter\";\nimport { type MaybeAsyncCallback, diverge } from \"../utils\";\n\ntype VitestExpect = typeof expect;\n\nfunction toHaveErrorImpl(\n\tcontext: MatcherState,\n\texpect: VitestExpect,\n\tactual: Report,\n\texpected: Partial<Message>,\n): SyncExpectationResult {\n\tconst flattened = actual.results.flatMap((result) => result.messages);\n\tconst matcher = [expect.objectContaining(expected)];\n\tconst pass = context.equals(flattened, matcher);\n\tconst diffString = context.utils.diff(matcher, flattened);\n\tconst hint = context.utils.matcherHint(\".toHaveError\");\n\tconst prettyExpected = context.utils.printExpected(matcher);\n\tconst prettyReceived = context.utils.printReceived(flattened);\n\tconst resultMessage = (): string => {\n\t\treturn [\n\t\t\thint,\n\t\t\t\"\",\n\t\t\t\"Expected error to equal:\",\n\t\t\t` ${prettyExpected}`,\n\t\t\t\"Received:\",\n\t\t\t` ${prettyReceived}`,\n\t\t\t/* istanbul ignore next */ diffString ? `\\nDifference:\\n\\n${diffString}` : \"\",\n\t\t].join(\"\\n\");\n\t};\n\treturn { pass, message: resultMessage, actual: flattened, expected: matcher };\n}\n\nfunction createMatcher(\n\texpect: VitestExpect,\n):\n\t| MaybeAsyncCallback<Report, [Partial<Message>]>\n\t| MaybeAsyncCallback<Report, [string, string, unknown?]> {\n\tfunction toHaveError(\n\t\tthis: MatcherState,\n\t\tactual: Report,\n\t\terror: Partial<Message>,\n\t): SyncExpectationResult;\n\tfunction toHaveError(\n\t\tthis: MatcherState,\n\t\tactual: Report,\n\t\truleId: string,\n\t\tmessage: string,\n\t\tcontext?: unknown,\n\t): SyncExpectationResult;\n\tfunction toHaveError(\n\t\tthis: MatcherState,\n\t\tactual: Report,\n\t\targ1: string | Partial<Message>,\n\t\targ2?: string,\n\t\targ3?: unknown,\n\t): SyncExpectationResult {\n\t\tif (typeof arg1 === \"string\") {\n\t\t\tconst expected: Partial<Message> = {\n\t\t\t\truleId: arg1,\n\t\t\t\tmessage: arg2,\n\t\t\t};\n\t\t\tif (arg3 !== undefined) {\n\t\t\t\texpected.context = arg3;\n\t\t\t}\n\t\t\treturn toHaveErrorImpl(this, expect, actual, expected);\n\t\t} else {\n\t\t\treturn toHaveErrorImpl(this, expect, actual, arg1);\n\t\t}\n\t}\n\treturn diverge(toHaveError);\n}\n\nexport { createMatcher as toHaveError };\n","/* eslint-disable prefer-template -- technical debt, should be refactored */\n\nimport { type MatcherState, type SyncExpectationResult } from \"@vitest/expect\";\nimport { type expect } from \"vitest\";\nimport { type Report } from \"../../reporter\";\nimport { type MaybeAsyncCallback, diverge } from \"../utils\";\n\ntype VitestExpect = typeof expect;\n\nfunction createMatcher(\n\texpect: VitestExpect,\n): MaybeAsyncCallback<Report, [Array<[string, string] | Record<string, unknown>>]> {\n\tfunction toHaveErrors(\n\t\tthis: MatcherState,\n\t\treport: Report,\n\t\terrors: Array<[string, string] | Record<string, unknown>>,\n\t): SyncExpectationResult {\n\t\tconst flattened = report.results.flatMap((result) => result.messages);\n\t\tconst matcher = errors.map((entry) => {\n\t\t\tif (Array.isArray(entry)) {\n\t\t\t\tconst [ruleId, message] = entry;\n\t\t\t\t/* eslint-disable-next-line @typescript-eslint/no-unsafe-return -- upstream typing */\n\t\t\t\treturn expect.objectContaining({ ruleId, message });\n\t\t\t} else {\n\t\t\t\t/* eslint-disable-next-line @typescript-eslint/no-unsafe-return -- upstream typing */\n\t\t\t\treturn expect.objectContaining(entry);\n\t\t\t}\n\t\t});\n\t\tconst pass = this.equals(flattened, matcher);\n\t\tconst diffString = this.utils.diff(matcher, flattened);\n\t\tconst resultMessage = (): string =>\n\t\t\tthis.utils.matcherHint(\".toHaveErrors\") +\n\t\t\t\"\\n\\n\" +\n\t\t\t\"Expected error to equal:\\n\" +\n\t\t\t` ${this.utils.printExpected(matcher)}\\n` +\n\t\t\t\"Received:\\n\" +\n\t\t\t` ${this.utils.printReceived(flattened)}` +\n\t\t\t/* istanbul ignore next */ (diffString ? `\\n\\nDifference:\\n\\n${diffString}` : \"\");\n\n\t\treturn { pass, message: resultMessage };\n\t}\n\treturn diverge(toHaveErrors);\n}\n\nexport { createMatcher as toHaveErrors };\n","import { type AsyncExpectationResult, type MatcherState } from \"@vitest/expect\";\nimport * as vitest from \"vitest\";\nimport { HtmlValidate } from \"../../htmlvalidate\";\nimport { type Report } from \"../../reporter\";\nimport { codeframe } from \"../utils\";\n\ntype ToMatchCodeframeMatcher = (\n\tthis: MatcherState,\n\treceived: Report | string | Promise<Report> | Promise<string>,\n\thint?: string,\n) => AsyncExpectationResult;\n\nfunction createMatcher(): ToMatchCodeframeMatcher {\n\tconst htmlvalidate = new HtmlValidate();\n\n\tasync function toMatchCodeframe(\n\t\tthis: MatcherState,\n\t\treceived: Report | string | Promise<Report> | Promise<string>,\n\t\thint?: string,\n\t): AsyncExpectationResult {\n\t\t/* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- for backwards compatibility with older vitest versions */\n\t\tif (!vitest.Snapshots) {\n\t\t\tthrow new Error(\"toMatchCodeframe() requires vitest 4.1.3 or later. Please upgrade vitest.\");\n\t\t}\n\n\t\tconst resolved = await received;\n\n\t\tlet report: Report;\n\t\tif (typeof resolved === \"string\") {\n\t\t\treport = await htmlvalidate.validateString(resolved);\n\t\t} else {\n\t\t\treport = resolved;\n\t\t}\n\n\t\tconst snapshot = codeframe(report.results).replaceAll(/\\s+$/gm, \"\");\n\n\t\treturn vitest.Snapshots.toMatchSnapshot.call(this, snapshot, hint);\n\t}\n\n\treturn toMatchCodeframe;\n}\n\nexport { createMatcher as toMatchCodeframe };\n","import { type AsyncExpectationResult, type MatcherState } from \"@vitest/expect\";\nimport * as vitest from \"vitest\";\nimport { HtmlValidate } from \"../../htmlvalidate\";\nimport { type Report } from \"../../reporter\";\nimport { codeframe } from \"../utils\";\n\ntype ToMatchInlineCodeframeMatcher = (\n\tthis: MatcherState,\n\treceived: Report | string | Promise<Report> | Promise<string>,\n\tinlineSnapshot?: string,\n) => AsyncExpectationResult;\n\nfunction createMatcher(): ToMatchInlineCodeframeMatcher {\n\tconst htmlvalidate = new HtmlValidate();\n\n\tasync function toMatchInlineCodeframe(\n\t\tthis: MatcherState,\n\t\treceived: Report | string | Promise<Report> | Promise<string>,\n\t\tinlineSnapshot?: string,\n\t): AsyncExpectationResult {\n\t\t/* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- for backwards compatibility with older vitest versions */\n\t\tif (!vitest.Snapshots) {\n\t\t\tthrow new Error(\n\t\t\t\t\"toMatchInlineCodeframe() requires vitest 4.1.3 or later. Please upgrade vitest.\",\n\t\t\t);\n\t\t}\n\n\t\t/* Capture the call site synchronously before any await — vitest needs this\n\t\t * to determine where to rewrite the inline snapshot in the source file. */\n\t\tvitest.chai.util.flag(this.assertion, \"error\", new Error(\"stacktrace\"));\n\n\t\tconst resolved = await received;\n\n\t\tlet report: Report;\n\t\tif (typeof resolved === \"string\") {\n\t\t\treport = await htmlvalidate.validateString(resolved);\n\t\t} else {\n\t\t\treport = resolved;\n\t\t}\n\n\t\tconst snapshot = codeframe(report.results).replaceAll(/\\s+$/gm, \"\");\n\n\t\treturn vitest.Snapshots.toMatchInlineSnapshot.call(this, snapshot, inlineSnapshot);\n\t}\n\n\treturn toMatchInlineCodeframe;\n}\n\nexport { createMatcher as toMatchInlineCodeframe };\n"],"names":["createMatcher","diverge","deepmerge","createSyncFn","vitestWorkerPath","actual","HtmlValidate","vitest","codeframe"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,SAASA,eAAA,GAAgD;AACxD,EAAA,SAAS,UAAU,MAAA,EAAuC;AACzD,IAAA,IAAI,OAAO,KAAA,EAAO;AACjB,MAAA,OAAO;AAAA,QACN,IAAA,EAAM,IAAA;AAAA,QACN,OAAA;AAAA;AAAA,UAAoC,MAAM;AAAA;AAAA,OAC3C;AAAA,IACD,CAAA,MAAO;AACN,MAAA,MAAM,aAAa,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA,CAAE,SAAS,CAAC,CAAA;AAC/C,MAAA,OAAO;AAAA,QACN,IAAA,EAAM,KAAA;AAAA,QACN,OAAA,EAAS,MAAM,CAAA,sCAAA,EAAyC,UAAA,CAAW,OAAO,CAAA,CAAA;AAAA,OAC3E;AAAA,IACD;AAAA,EACD;AACA,EAAA,OAAOC,oBAAQ,SAAS,CAAA;AACzB;;AChBA,SAASD,eAAA,GAAgD;AACxD,EAAA,SAAS,YAAY,MAAA,EAAuC;AAC3D,IAAA,IAAI,OAAO,KAAA,EAAO;AACjB,MAAA,OAAO;AAAA,QACN,IAAA,EAAM,KAAA;AAAA,QACN,SAAS,MAAM;AAAA,OAChB;AAAA,IACD,CAAA,MAAO;AACN,MAAA,OAAO;AAAA,QACN,IAAA,EAAM,IAAA;AAAA,QACN,OAAA;AAAA;AAAA,UAAoC,MAAM;AAAA;AAAA,OAC3C;AAAA,IACD;AAAA,EACD;AACA,EAAA,OAAOC,oBAAQ,WAAW,CAAA;AAC3B;;ACTA,SAAS,UAAU,GAAA,EAAgD;AAClE,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACpC,IAAA,OAAO,KAAA;AAAA,EACR;AACA,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,QAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACD,CAAE,IAAA,CAAK,CAAC,GAAA,KAAQ,OAAO,GAAG,CAAA;AAC3B;AAEA,SAAS,SAAS,GAAA,EAA0C;AAC3D,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACpC,IAAA,OAAO,KAAA;AAAA,EACR;AACA,EAAA,OAAO,CAAC,MAAA,EAAQ,SAAA,EAAW,UAAA,EAAY,QAAA,EAAU,WAAA,EAAa,OAAO,CAAA,CAAE,IAAA,CAAK,CAAC,GAAA,KAAQ,GAAA,IAAO,GAAG,CAAA;AAChG;AAEA,SAAS,SAAS,GAAA,EAAsC;AACvD,EAAA,OAAO,OAAO,GAAA,KAAQ,QAAA;AACvB;AAEA,SAAS,UAAU,GAAA,EAAsB;AACxC,EAAA,IAAI,OAAO,WAAA,KAAgB,WAAA,IAAe,GAAA,YAAe,WAAA,EAAa;AACrE,IAAA,OAAQ,GAAA,CAA8B,SAAA;AAAA,EACvC;AAEA,EAAA,IAAI,OAAO,QAAQ,QAAA,EAAU;AAC5B,IAAA,OAAO,GAAA;AAAA,EACR,CAAA,MAAO;AACN,IAAA,MAAM,IAAI,SAAA,CAAU,CAAA,2BAAA,EAA8B,OAAO,GAAG,CAAA,UAAA,CAAY,CAAA;AAAA,EACzE;AACD;AAMA,SAASD,gBAAc,MAAA,EAA0E;AAChG,EAAA,SAAS,cAAA,CAER,MAAA,EACA,IAAA,EACA,IAAA,EACA,IAAA,EACwB;AACxB,IAAA,MAAM,MAAA,GAAS,UAAU,MAAM,CAAA;AAC/B,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,IAAI,CAAA,GAAI,IAAA,GAAO,MAAA;AACzC,IAAA,MAAM,MAAA,GAAS,SAAS,IAAI,CAAA,GAAI,OAAO,QAAA,CAAS,IAAI,IAAI,IAAA,GAAO,MAAA;AAC/D,IAAA,MAAM,QAAA,GAAW,SAAS,IAAI,CAAA,GAAI,OAAO,QAAA,CAAS,IAAI,IAAI,IAAA,GAAO,IAAA;AACjE,IAAA,OAAO,mBAAmB,IAAA,CAAK,IAAA,EAAM,QAAQ,MAAA,EAAQ,OAAA,EAAS,QAAQ,QAAQ,CAAA;AAAA,EAC/E;AACA,EAAA,OAAOC,oBAAQ,cAAc,CAAA;AAC9B;AAGA,SAAS,kBAAA,CAER,MAAA,EACA,MAAA,EACA,aAAA,EACA,YACA,QAAA,EACwB;AACxB,EAAA,MAAM,aAAA,GAAgB;AAAA,IACrB,KAAA,EAAO;AAAA;AAAA;AAAA,MAGN,YAAA,EAAc;AAAA;AACf,GACD;AACA,EAAA,MAAM,MAAA,GAASC,cAAA,CAAU,aAAA,EAAe,UAAA,IAAc,EAAE,CAAA;AAExD,EAAA,MAAM,cAAA,GAAiB,QAAA,IAAY,IAAA,CAAK,QAAA,IAAY,QAAA;AAEpD,EAAA,MAAM,MAAA,GAASC,yBAA+BC,qBAAgB,CAAA;AAC9D,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,MAAA,EAAQ,cAAA,EAAgB,MAAM,CAAA;AACpD,EAAA,MAAM,OAAO,MAAA,CAAO,KAAA;AACpB,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,OAAA,CAAQ,CAAC,CAAA;AAC/B,EAAA,IAAI,IAAA,EAAM;AACT,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,MAAM,0CAAA,EAA2C;AAAA,EAC1E,CAAA,MAAO;AACN,IAAA,IAAI,aAAA,EAAe;AAClB,MAAA,MAAMC,UAAS,MAAA,CAAO,QAAA;AAEtB,MAAA,MAAM,QAAA,GAAW,OAAO,eAAA,CAAgB,CAAC,OAAO,gBAAA,CAAiB,aAAa,CAAC,CAAC,CAAA;AAChF,MAAA,MAAM,SAAA,GAAY,IAAA,CAAK,MAAA,CAAOA,OAAAA,EAAQ,QAAQ,CAAA;AAC9C,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,UAAUA,OAAAA,EAAQ;AAAA,QACpD,WAAA,EAAa,gBAAA;AAAA,QACb,WAAA,EAAa;AAAA,OACb,CAAA;AACD,MAAA,MAAM,OAAO,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,qBAAA,EAAuB,QAAW,MAAA,EAAW;AAAA,QAChF,OAAA,EAAS;AAAA,OACT,CAAA;AACD,MAAA,MAAM,uBAAuB,MAC5B;AAAA,QACC,IAAA;AAAA,QACA,EAAA;AAAA,QACA,+BAAA;AAAA,QACA,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,aAAa,CAAA;AAAA;AAAA,QACX,UAAA,GAAa;AAAA,EAAK,UAAU,CAAA,CAAA,GAAK;AAAA,OAC7D,CAAE,KAAK,IAAI,CAAA;AAEZ,MAAA,OAAO,EAAE,MAAM,CAAC,SAAA,EAAW,SAAS,oBAAA,EAAsB,MAAA,EAAAA,SAAQ,QAAA,EAAS;AAAA,IAC5E;AAEA,IAAA,MAAM,MAAA,GAAS,MAAA,CAAO,QAAA,CAAS,GAAA,CAAI,CAAC,OAAA,KAAY,CAAA,EAAA,EAAK,OAAA,CAAQ,OAAO,CAAA,EAAA,EAAK,OAAA,CAAQ,MAAM,CAAA,CAAA,CAAG,CAAA;AAC1F,IAAA,OAAO;AAAA,MACN,IAAA;AAAA,MACA,OAAA,EAAS,MACR,CAAC,yDAAA,EAA2D,EAAE,EAAE,MAAA,CAAO,MAAM,CAAA,CAAE,IAAA,CAAK,IAAI;AAAA,KAC1F;AAAA,EACD;AACD;;ACzHA,SAAS,eAAA,CACR,OAAA,EACA,MAAA,EACA,MAAA,EACA,QAAA,EACwB;AACxB,EAAA,MAAM,YAAY,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAC,MAAA,KAAW,OAAO,QAAQ,CAAA;AACpE,EAAA,MAAM,OAAA,GAAU,CAAC,MAAA,CAAO,gBAAA,CAAiB,QAAQ,CAAC,CAAA;AAClD,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,MAAA,CAAO,SAAA,EAAW,OAAO,CAAA;AAC9C,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,KAAA,CAAM,IAAA,CAAK,SAAS,SAAS,CAAA;AACxD,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,WAAA,CAAY,cAAc,CAAA;AACrD,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,KAAA,CAAM,aAAA,CAAc,OAAO,CAAA;AAC1D,EAAA,MAAM,cAAA,GAAiB,OAAA,CAAQ,KAAA,CAAM,aAAA,CAAc,SAAS,CAAA;AAC5D,EAAA,MAAM,gBAAgB,MAAc;AACnC,IAAA,OAAO;AAAA,MACN,IAAA;AAAA,MACA,EAAA;AAAA,MACA,0BAAA;AAAA,MACA,KAAK,cAAc,CAAA,CAAA;AAAA,MACnB,WAAA;AAAA,MACA,KAAK,cAAc,CAAA,CAAA;AAAA;AAAA,MACQ,UAAA,GAAa;AAAA;;AAAA,EAAoB,UAAU,CAAA,CAAA,GAAK;AAAA,KAC5E,CAAE,KAAK,IAAI,CAAA;AAAA,EACZ,CAAA;AACA,EAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,eAAe,MAAA,EAAQ,SAAA,EAAW,UAAU,OAAA,EAAQ;AAC7E;AAEA,SAASL,gBACR,MAAA,EAGyD;AAazD,EAAA,SAAS,WAAA,CAER,MAAA,EACA,IAAA,EACA,IAAA,EACA,IAAA,EACwB;AACxB,IAAA,IAAI,OAAO,SAAS,QAAA,EAAU;AAC7B,MAAA,MAAM,QAAA,GAA6B;AAAA,QAClC,MAAA,EAAQ,IAAA;AAAA,QACR,OAAA,EAAS;AAAA,OACV;AACA,MAAA,IAAI,SAAS,MAAA,EAAW;AACvB,QAAA,QAAA,CAAS,OAAA,GAAU,IAAA;AAAA,MACpB;AACA,MAAA,OAAO,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,QAAQ,CAAA;AAAA,IACtD,CAAA,MAAO;AACN,MAAA,OAAO,eAAA,CAAgB,IAAA,EAAM,MAAA,EAAQ,MAAA,EAAQ,IAAI,CAAA;AAAA,IAClD;AAAA,EACD;AACA,EAAA,OAAOC,oBAAQ,WAAW,CAAA;AAC3B;;AChEA,SAASD,gBACR,MAAA,EACkF;AAClF,EAAA,SAAS,YAAA,CAER,QACA,MAAA,EACwB;AACxB,IAAA,MAAM,YAAY,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAC,MAAA,KAAW,OAAO,QAAQ,CAAA;AACpE,IAAA,MAAM,OAAA,GAAU,MAAA,CAAO,GAAA,CAAI,CAAC,KAAA,KAAU;AACrC,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,KAAK,CAAA,EAAG;AACzB,QAAA,MAAM,CAAC,MAAA,EAAQ,OAAO,CAAA,GAAI,KAAA;AAE1B,QAAA,OAAO,MAAA,CAAO,gBAAA,CAAiB,EAAE,MAAA,EAAQ,SAAS,CAAA;AAAA,MACnD,CAAA,MAAO;AAEN,QAAA,OAAO,MAAA,CAAO,iBAAiB,KAAK,CAAA;AAAA,MACrC;AAAA,IACD,CAAC,CAAA;AACD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,CAAO,SAAA,EAAW,OAAO,CAAA;AAC3C,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,IAAA,CAAK,SAAS,SAAS,CAAA;AACrD,IAAA,MAAM,gBAAgB,MACrB,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,eAAe,CAAA,GACtC;;AAAA;AAAA,EAAA,EAEK,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,OAAO,CAAC;AAAA;AAAA,EAAA,EAEjC,IAAA,CAAK,KAAA,CAAM,aAAA,CAAc,SAAS,CAAC,CAAA,CAAA;AAAA,KACZ,UAAA,GAAa;;AAAA;;AAAA,EAAsB,UAAU,CAAA,CAAA,GAAK,EAAA,CAAA;AAE/E,IAAA,OAAO,EAAE,IAAA,EAAM,OAAA,EAAS,aAAA,EAAc;AAAA,EACvC;AACA,EAAA,OAAOC,oBAAQ,YAAY,CAAA;AAC5B;;AC9BA,SAASD,eAAA,GAAyC;AACjD,EAAA,MAAM,YAAA,GAAe,IAAIM,uBAAA,EAAa;AAEtC,EAAA,eAAe,gBAAA,CAEd,UACA,IAAA,EACyB;AAEzB,IAAA,IAAI,CAACC,kBAAO,SAAA,EAAW;AACtB,MAAA,MAAM,IAAI,MAAM,2EAA2E,CAAA;AAAA,IAC5F;AAEA,IAAA,MAAM,WAAW,MAAM,QAAA;AAEvB,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,OAAO,aAAa,QAAA,EAAU;AACjC,MAAA,MAAA,GAAS,MAAM,YAAA,CAAa,cAAA,CAAe,QAAQ,CAAA;AAAA,IACpD,CAAA,MAAO;AACN,MAAA,MAAA,GAAS,QAAA;AAAA,IACV;AAEA,IAAA,MAAM,WAAWC,qBAAA,CAAU,MAAA,CAAO,OAAO,CAAA,CAAE,UAAA,CAAW,UAAU,EAAE,CAAA;AAElE,IAAA,OAAOD,kBAAO,SAAA,CAAU,eAAA,CAAgB,IAAA,CAAK,IAAA,EAAM,UAAU,IAAI,CAAA;AAAA,EAClE;AAEA,EAAA,OAAO,gBAAA;AACR;;AC5BA,SAAS,aAAA,GAA+C;AACvD,EAAA,MAAM,YAAA,GAAe,IAAID,uBAAA,EAAa;AAEtC,EAAA,eAAe,sBAAA,CAEd,UACA,cAAA,EACyB;AAEzB,IAAA,IAAI,CAACC,kBAAO,SAAA,EAAW;AACtB,MAAA,MAAM,IAAI,KAAA;AAAA,QACT;AAAA,OACD;AAAA,IACD;AAIA,IAAAA,iBAAA,CAAO,IAAA,CAAK,KAAK,IAAA,CAAK,IAAA,CAAK,WAAW,OAAA,EAAS,IAAI,KAAA,CAAM,YAAY,CAAC,CAAA;AAEtE,IAAA,MAAM,WAAW,MAAM,QAAA;AAEvB,IAAA,IAAI,MAAA;AACJ,IAAA,IAAI,OAAO,aAAa,QAAA,EAAU;AACjC,MAAA,MAAA,GAAS,MAAM,YAAA,CAAa,cAAA,CAAe,QAAQ,CAAA;AAAA,IACpD,CAAA,MAAO;AACN,MAAA,MAAA,GAAS,QAAA;AAAA,IACV;AAEA,IAAA,MAAM,WAAWC,qBAAA,CAAU,MAAA,CAAO,OAAO,CAAA,CAAE,UAAA,CAAW,UAAU,EAAE,CAAA;AAElE,IAAA,OAAOD,kBAAO,SAAA,CAAU,qBAAA,CAAsB,IAAA,CAAK,IAAA,EAAM,UAAU,cAAc,CAAA;AAAA,EAClF;AAEA,EAAA,OAAO,sBAAA;AACR;;;;;;;;;;"}
@@ -0,0 +1,120 @@
1
+ 'use strict';
2
+
3
+ var core = require('./core.js');
4
+ var node_worker_threads = require('node:worker_threads');
5
+ var coreNodejs = require('./core-nodejs.js');
6
+
7
+ function formatMessage(message, parentResult) {
8
+ const type = message.severity === 2 ? "error" : "warning";
9
+ const msg = message.message.replace(/([^ ])\.$/, "$1");
10
+ const ruleId = `(${message.ruleId})`;
11
+ const sourceCode = parentResult.source;
12
+ const firstLine = [`${type}:`, msg, ruleId].join(" ");
13
+ const result = [firstLine];
14
+ if (sourceCode) {
15
+ const output = core.codeFrameColumns(sourceCode, {
16
+ start: core.getStartLocation(message),
17
+ end: core.getEndLocation(message, sourceCode)
18
+ });
19
+ result.push(output);
20
+ }
21
+ result.push(`Selector: ${message.selector ?? "-"}`);
22
+ return result.join("\n");
23
+ }
24
+ function codeframe(results) {
25
+ let errors = 0;
26
+ let warnings = 0;
27
+ const resultsWithMessages = results.filter((result) => result.messages.length > 0);
28
+ const output = resultsWithMessages.reduce((resultsOutput, result) => {
29
+ const messages = result.messages.map((message) => {
30
+ return `${formatMessage(message, result)}
31
+
32
+ `;
33
+ });
34
+ errors += result.errorCount;
35
+ warnings += result.warningCount;
36
+ return resultsOutput.concat(messages);
37
+ }, []).join("\n");
38
+ return errors + warnings > 0 ? output : "";
39
+ }
40
+
41
+ function isThenable(value) {
42
+ return value && typeof value === "object" && "then" in value && typeof value.then === "function";
43
+ }
44
+
45
+ function diverge(fn) {
46
+ function diverged(actual, ...args) {
47
+ if (isThenable(actual)) {
48
+ return actual.then((resolved) => fn.call(this, resolved, ...args));
49
+ } else {
50
+ return fn.call(this, actual, ...args);
51
+ }
52
+ }
53
+ return diverged;
54
+ }
55
+
56
+ const INT32_BYTES = 4;
57
+ const syncFnCache = /* @__PURE__ */ new Map();
58
+ const sharedBuffer = new SharedArrayBuffer(INT32_BYTES);
59
+ const sharedBufferView = new Int32Array(sharedBuffer, 0, 1);
60
+ function isWorkerError(value) {
61
+ return "error" in value;
62
+ }
63
+ function receiveMessageWithId(port, expectedId) {
64
+ const timeout = 3e4;
65
+ const status = Atomics.wait(sharedBufferView, 0, 0, timeout);
66
+ Atomics.store(sharedBufferView, 0, 0);
67
+ if (!["ok", "not-equal"].includes(status)) {
68
+ const abortMsg = {
69
+ id: expectedId,
70
+ cmd: "abort"
71
+ };
72
+ port.postMessage(abortMsg);
73
+ throw new Error(`Internal error: Atomics.wait() failed: ${status}`);
74
+ }
75
+ const reply = node_worker_threads.receiveMessageOnPort(port);
76
+ const { id, ...message } = reply.message;
77
+ if (id < expectedId) {
78
+ return receiveMessageWithId(port, expectedId);
79
+ }
80
+ if (expectedId !== id) {
81
+ throw new Error(`Internal error: Expected id ${String(expectedId)} but got id ${String(id)}`);
82
+ }
83
+ return { id, ...message };
84
+ }
85
+ function startWorkerThread(workerPath) {
86
+ const { port1: mainPort, port2: workerPort } = new node_worker_threads.MessageChannel();
87
+ const workerPathUrl = coreNodejs.legacyRequire.resolve(workerPath);
88
+ const worker = new node_worker_threads.Worker(workerPathUrl, {
89
+ eval: false,
90
+ workerData: { sharedBuffer, workerPort },
91
+ transferList: [workerPort]
92
+ });
93
+ let nextID = 0;
94
+ const syncFn = (...args) => {
95
+ const id = nextID++;
96
+ const msg = { id, args };
97
+ worker.postMessage(msg);
98
+ const reply = receiveMessageWithId(mainPort, id);
99
+ if (isWorkerError(reply)) {
100
+ throw new Error(reply.error);
101
+ }
102
+ return reply.result;
103
+ };
104
+ worker.unref();
105
+ return syncFn;
106
+ }
107
+ function createSyncFn(workerPath) {
108
+ const cachedSyncFn = syncFnCache.get(workerPath);
109
+ if (cachedSyncFn) {
110
+ return cachedSyncFn;
111
+ }
112
+ const syncFn = startWorkerThread(workerPath);
113
+ syncFnCache.set(workerPath, syncFn);
114
+ return syncFn;
115
+ }
116
+
117
+ exports.codeframe = codeframe;
118
+ exports.createSyncFn = createSyncFn;
119
+ exports.diverge = diverge;
120
+ //# sourceMappingURL=vitest-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-utils.js","sources":["../../src/vitest/utils/codeframe.ts","../../src/vitest/utils/is-thenable.ts","../../src/vitest/utils/diverge.ts","../../src/vitest/worker/create-sync-fn.ts"],"sourcesContent":["import { type Message } from \"../../message\";\nimport { type Result } from \"../../reporter\";\nimport { codeFrameColumns } from \"../../utils/code-frame-columns\";\nimport { getEndLocation, getStartLocation } from \"../../utils/message-location\";\n\n/**\n * Gets the formatted output for a given message.\n * @param message - The object that represents this message.\n * @param parentResult - The result object that this message belongs to.\n * @returns The formatted output.\n */\nfunction formatMessage(message: Message, parentResult: Result): string {\n\tconst type = message.severity === 2 ? \"error\" : \"warning\";\n\tconst msg = message.message.replace(/([^ ])\\.$/, \"$1\");\n\tconst ruleId = `(${message.ruleId})`;\n\tconst sourceCode = parentResult.source;\n\tconst firstLine = [`${type}:`, msg, ruleId].join(\" \");\n\tconst result = [firstLine];\n\n\t/* istanbul ignore next: safety check from original implementation */\n\tif (sourceCode) {\n\t\tconst output = codeFrameColumns(sourceCode, {\n\t\t\tstart: getStartLocation(message),\n\t\t\tend: getEndLocation(message, sourceCode),\n\t\t});\n\t\tresult.push(output);\n\t}\n\n\tresult.push(`Selector: ${message.selector ?? \"-\"}`);\n\n\treturn result.join(\"\\n\");\n}\n\n/**\n * Codeframe formatter based on ESLint codeframe.\n *\n * @internal\n */\nexport function codeframe(results: Result[]): string {\n\tlet errors = 0;\n\tlet warnings = 0;\n\n\tconst resultsWithMessages = results.filter((result) => result.messages.length > 0);\n\n\tconst output = resultsWithMessages\n\t\t.reduce<string[]>((resultsOutput, result) => {\n\t\t\tconst messages = result.messages.map((message) => {\n\t\t\t\treturn `${formatMessage(message, result)}\\n\\n`;\n\t\t\t});\n\n\t\t\terrors += result.errorCount;\n\t\t\twarnings += result.warningCount;\n\n\t\t\treturn resultsOutput.concat(messages);\n\t\t}, [])\n\t\t.join(\"\\n\");\n\n\treturn errors + warnings > 0 ? output : \"\";\n}\n","/**\n * @internal\n */\nexport function isThenable<T>(value: T | Promise<T>): value is Promise<T> {\n\treturn value && typeof value === \"object\" && \"then\" in value && typeof value.then === \"function\";\n}\n","import {\n\ttype AsyncExpectationResult,\n\ttype MatcherState,\n\ttype SyncExpectationResult,\n} from \"@vitest/expect\";\nimport { isThenable } from \"./is-thenable\";\n\ntype SyncCallback<T, TArgs extends unknown[]> = (\n\tthis: MatcherState,\n\tactual: T,\n\t...args: TArgs\n) => SyncExpectationResult;\n\n/**\n * @internal\n */\nexport interface MaybeAsyncCallback<TActual, TArgs extends unknown[]> {\n\t(this: MatcherState, actual: TActual, ...args: TArgs): SyncExpectationResult;\n\t(this: MatcherState, actual: Promise<TActual>, ...args: TArgs): AsyncExpectationResult;\n}\n\n/**\n * Creates a wrapped function based on the passed function.\n *\n * The returned function takes either a `T` or `Promise<T>`. If `T` the result\n * will be synchronous or if `Promise<T>` the result will be asynchronous.\n *\n * In practice this means that if you pass a synchronous object into it you will\n * maintain synchronous code but if you pass an asynchronous object you must\n * await the result.\n *\n * @internal\n */\nexport function diverge<T, TArgs extends unknown[]>(\n\tfn: SyncCallback<T, TArgs>,\n): MaybeAsyncCallback<T, TArgs> {\n\tfunction diverged(this: MatcherState, actual: T, ...args: TArgs): SyncExpectationResult;\n\tfunction diverged(this: MatcherState, actual: Promise<T>, ...args: TArgs): AsyncExpectationResult;\n\tfunction diverged(\n\t\tthis: MatcherState,\n\t\tactual: T | Promise<T>,\n\t\t...args: TArgs\n\t): SyncExpectationResult | AsyncExpectationResult {\n\t\tif (isThenable(actual)) {\n\t\t\treturn actual.then((resolved) => fn.call(this, resolved, ...args));\n\t\t} else {\n\t\t\treturn fn.call(this, actual, ...args);\n\t\t}\n\t}\n\treturn diverged;\n}\n","import {\n\ttype MessagePort,\n\tMessageChannel,\n\tWorker,\n\treceiveMessageOnPort,\n} from \"node:worker_threads\";\nimport { legacyRequire } from \"../../resolve\";\nimport {\n\ttype AnyAsyncFn,\n\ttype AnyFn,\n\ttype MainToWorkerCommandMessage,\n\ttype MainToWorkerMessage,\n\ttype Syncify,\n\ttype WorkerToMainError,\n\ttype WorkerToMainMessage,\n} from \"./types\";\n\n/**\n * This is all based on the synckit library but without all the extra stuff such\n * as typescript, esbuld, pnp etc.\n */\n\nconst INT32_BYTES = 4;\nconst syncFnCache = new Map<string, AnyFn>();\nconst sharedBuffer = new SharedArrayBuffer(INT32_BYTES);\nconst sharedBufferView = new Int32Array(sharedBuffer, 0, 1);\n\nfunction isWorkerError<T>(value: WorkerToMainMessage<T>): value is WorkerToMainError {\n\treturn \"error\" in value;\n}\n\nfunction receiveMessageWithId<R>(port: MessagePort, expectedId: number): WorkerToMainMessage<R> {\n\t/* wait for the semaphore to be raised before receiving message */\n\tconst timeout = 30000;\n\tconst status = Atomics.wait(sharedBufferView, 0, 0, timeout);\n\tAtomics.store(sharedBufferView, 0, 0);\n\n\t/* handle timeout or unexpected errors */\n\tif (![\"ok\", \"not-equal\"].includes(status)) {\n\t\tconst abortMsg: MainToWorkerCommandMessage = {\n\t\t\tid: expectedId,\n\t\t\tcmd: \"abort\",\n\t\t};\n\t\tport.postMessage(abortMsg);\n\t\tthrow new Error(`Internal error: Atomics.wait() failed: ${status}`);\n\t}\n\n\t/* the worker process will post the message before raising the semaphore, we\n\t * should not reach this part of the code unless there is a message waiting to\n\t * be read */\n\tconst reply = receiveMessageOnPort(port) as { message: WorkerToMainMessage<R> };\n\tconst { id, ...message } = reply.message;\n\n\tif (id < expectedId) {\n\t\treturn receiveMessageWithId(port, expectedId);\n\t}\n\n\tif (expectedId !== id) {\n\t\tthrow new Error(`Internal error: Expected id ${String(expectedId)} but got id ${String(id)}`);\n\t}\n\n\treturn { id, ...message };\n}\n\nfunction startWorkerThread<R, T extends AnyAsyncFn<R>>(\n\tworkerPath: string,\n): (...args: Parameters<T>) => R {\n\tconst { port1: mainPort, port2: workerPort } = new MessageChannel();\n\tconst workerPathUrl = legacyRequire.resolve(workerPath);\n\tconst worker = new Worker(workerPathUrl, {\n\t\teval: false,\n\t\tworkerData: { sharedBuffer, workerPort },\n\t\ttransferList: [workerPort],\n\t});\n\n\tlet nextID = 0;\n\n\tconst syncFn = (...args: Parameters<T>): R => {\n\t\tconst id = nextID++;\n\t\tconst msg: MainToWorkerMessage<Parameters<T>> = { id, args };\n\n\t\tworker.postMessage(msg);\n\n\t\tconst reply = receiveMessageWithId<R>(mainPort, id);\n\n\t\tif (isWorkerError(reply)) {\n\t\t\tthrow new Error(reply.error);\n\t\t}\n\n\t\treturn reply.result;\n\t};\n\n\tworker.unref();\n\n\treturn syncFn;\n}\n\nexport function createSyncFn<T extends AnyAsyncFn<R>, R = unknown>(workerPath: string): Syncify<T> {\n\tconst cachedSyncFn = syncFnCache.get(workerPath);\n\tif (cachedSyncFn) {\n\t\treturn cachedSyncFn as Syncify<T>;\n\t}\n\n\tconst syncFn = startWorkerThread<R, T>(workerPath);\n\tsyncFnCache.set(workerPath, syncFn);\n\treturn syncFn as Syncify<T>;\n}\n"],"names":["codeFrameColumns","getStartLocation","getEndLocation","receiveMessageOnPort","MessageChannel","legacyRequire","Worker"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from "../types/vitest-worker";
@@ -0,0 +1,63 @@
1
+ 'use strict';
2
+
3
+ var node_worker_threads = require('node:worker_threads');
4
+ var coreNodejs = require('./core-nodejs.js');
5
+ require('node:fs');
6
+ require('./core.js');
7
+ require('ajv');
8
+ require('./elements.js');
9
+ require('./meta-helper.js');
10
+ require('./utils/natural-join.js');
11
+ require('./utils/parse-image-candidate-string.js');
12
+ require('@sidvind/better-ajv-errors');
13
+ require('kleur');
14
+ require('@html-validate/stylish');
15
+ require('semver');
16
+ require('node:path');
17
+ require('node:fs/promises');
18
+ require('node:url');
19
+
20
+ function runAsWorker(fn) {
21
+ if (!node_worker_threads.workerData) {
22
+ return;
23
+ }
24
+ const { workerPort, sharedBuffer } = node_worker_threads.workerData;
25
+ const sharedBufferView = new Int32Array(sharedBuffer, 0, 1);
26
+ node_worker_threads.parentPort.on("message", ({ id, args }) => {
27
+ async function inner() {
28
+ let isAborted = false;
29
+ const handleAbortMessage = (msg2) => {
30
+ if (msg2.id === id && msg2.cmd === "abort") {
31
+ isAborted = true;
32
+ }
33
+ };
34
+ workerPort.on("message", handleAbortMessage);
35
+ let msg;
36
+ try {
37
+ msg = { id, result: await fn(...args) };
38
+ } catch (error) {
39
+ msg = {
40
+ id,
41
+ error: error instanceof Error ? error.message : String(error)
42
+ };
43
+ }
44
+ workerPort.off("message", handleAbortMessage);
45
+ if (isAborted) {
46
+ return;
47
+ }
48
+ workerPort.postMessage(msg);
49
+ Atomics.add(sharedBufferView, 0, 1);
50
+ Atomics.notify(sharedBufferView, 0);
51
+ }
52
+ inner();
53
+ });
54
+ }
55
+ function validateString(markup, filename, config) {
56
+ const loader = new coreNodejs.FileSystemConfigLoader({
57
+ extends: ["html-validate:recommended"]
58
+ });
59
+ const htmlvalidate = new coreNodejs.HtmlValidate(loader);
60
+ return htmlvalidate.validateString(markup, filename, config);
61
+ }
62
+ runAsWorker(validateString);
63
+ //# sourceMappingURL=vitest-worker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vitest-worker.js","sources":["../../src/vitest/worker/vitest-worker.ts"],"sourcesContent":["import { type MessagePort, parentPort, workerData } from \"node:worker_threads\";\nimport { type ConfigData } from \"../../config\";\nimport { FileSystemConfigLoader } from \"../../config/loaders/file-system\";\nimport { HtmlValidate } from \"../../htmlvalidate\";\nimport { type Report } from \"../../reporter\";\nimport {\n\ttype AnyAsyncFn,\n\ttype MainToWorkerCommandMessage,\n\ttype MainToWorkerMessage,\n\ttype WorkerToMainMessage,\n} from \"./types\";\n\ninterface WorkerData {\n\tsharedBuffer: SharedArrayBuffer;\n\tworkerPort: MessagePort;\n}\n\n/* eslint-disable-next-line @typescript-eslint/no-unnecessary-type-parameters -- false positive, it is used in nested functions */\nfunction runAsWorker<R = unknown, T extends AnyAsyncFn<R> = AnyAsyncFn<R>>(fn: T): void {\n\tif (!workerData) {\n\t\treturn;\n\t}\n\n\tconst { workerPort, sharedBuffer } = workerData as WorkerData;\n\tconst sharedBufferView = new Int32Array(sharedBuffer, 0, 1);\n\n\t/* eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- better crash at runtime if not set */\n\tparentPort!.on(\"message\", ({ id, args }: MainToWorkerMessage<Parameters<T>>) => {\n\t\tasync function inner(): Promise<void> {\n\t\t\tlet isAborted = false;\n\t\t\tconst handleAbortMessage = (msg: MainToWorkerCommandMessage): void => {\n\t\t\t\tif (msg.id === id && msg.cmd === \"abort\") {\n\t\t\t\t\tisAborted = true;\n\t\t\t\t}\n\t\t\t};\n\t\t\tworkerPort.on(\"message\", handleAbortMessage);\n\t\t\tlet msg: WorkerToMainMessage<R>;\n\t\t\ttry {\n\t\t\t\tmsg = { id, result: await fn(...args) };\n\t\t\t} catch (error: unknown) {\n\t\t\t\tmsg = {\n\t\t\t\t\tid,\n\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t};\n\t\t\t}\n\t\t\tworkerPort.off(\"message\", handleAbortMessage);\n\n\t\t\t/* eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- it may have been set by `handleAbortMessage` */\n\t\t\tif (isAborted) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tworkerPort.postMessage(msg);\n\t\t\tAtomics.add(sharedBufferView, 0, 1);\n\t\t\tAtomics.notify(sharedBufferView, 0);\n\t\t}\n\t\t// eslint-disable-next-line @typescript-eslint/no-floating-promises -- should not happen\n\t\tinner();\n\t});\n}\n\nfunction validateString(markup: string, filename: string, config: ConfigData): Promise<Report> {\n\tconst loader = new FileSystemConfigLoader({\n\t\textends: [\"html-validate:recommended\"],\n\t});\n\tconst htmlvalidate = new HtmlValidate(loader);\n\treturn htmlvalidate.validateString(markup, filename, config);\n}\n\nexport type ValidateStringFn = typeof validateString;\n\nrunAsWorker(validateString);\n"],"names":["workerData","parentPort","msg","FileSystemConfigLoader","HtmlValidate"],"mappings":";;;;;;;;;;;;;;;;;;;AAkBA,SAAS,YAAkE,EAAA,EAAa;AACvF,EAAA,IAAI,CAACA,8BAAA,EAAY;AAChB,IAAA;AAAA,EACD;AAEA,EAAA,MAAM,EAAE,UAAA,EAAY,YAAA,EAAa,GAAIA,8BAAA;AACrC,EAAA,MAAM,gBAAA,GAAmB,IAAI,UAAA,CAAW,YAAA,EAAc,GAAG,CAAC,CAAA;AAG1D,EAAAC,8BAAA,CAAY,GAAG,SAAA,EAAW,CAAC,EAAE,EAAA,EAAI,MAAK,KAA0C;AAC/E,IAAA,eAAe,KAAA,GAAuB;AACrC,MAAA,IAAI,SAAA,GAAY,KAAA;AAChB,MAAA,MAAM,kBAAA,GAAqB,CAACC,IAAAA,KAA0C;AACrE,QAAA,IAAIA,IAAAA,CAAI,EAAA,KAAO,EAAA,IAAMA,IAAAA,CAAI,QAAQ,OAAA,EAAS;AACzC,UAAA,SAAA,GAAY,IAAA;AAAA,QACb;AAAA,MACD,CAAA;AACA,MAAA,UAAA,CAAW,EAAA,CAAG,WAAW,kBAAkB,CAAA;AAC3C,MAAA,IAAI,GAAA;AACJ,MAAA,IAAI;AACH,QAAA,GAAA,GAAM,EAAE,EAAA,EAAI,MAAA,EAAQ,MAAM,EAAA,CAAG,GAAG,IAAI,CAAA,EAAE;AAAA,MACvC,SAAS,KAAA,EAAgB;AACxB,QAAA,GAAA,GAAM;AAAA,UACL,EAAA;AAAA,UACA,OAAO,KAAA,YAAiB,KAAA,GAAQ,KAAA,CAAM,OAAA,GAAU,OAAO,KAAK;AAAA,SAC7D;AAAA,MACD;AACA,MAAA,UAAA,CAAW,GAAA,CAAI,WAAW,kBAAkB,CAAA;AAG5C,MAAA,IAAI,SAAA,EAAW;AACd,QAAA;AAAA,MACD;AACA,MAAA,UAAA,CAAW,YAAY,GAAG,CAAA;AAC1B,MAAA,OAAA,CAAQ,GAAA,CAAI,gBAAA,EAAkB,CAAA,EAAG,CAAC,CAAA;AAClC,MAAA,OAAA,CAAQ,MAAA,CAAO,kBAAkB,CAAC,CAAA;AAAA,IACnC;AAEA,IAAA,KAAA,EAAM;AAAA,EACP,CAAC,CAAA;AACF;AAEA,SAAS,cAAA,CAAe,MAAA,EAAgB,QAAA,EAAkB,MAAA,EAAqC;AAC9F,EAAA,MAAM,MAAA,GAAS,IAAIC,iCAAA,CAAuB;AAAA,IACzC,OAAA,EAAS,CAAC,2BAA2B;AAAA,GACrC,CAAA;AACD,EAAA,MAAM,YAAA,GAAe,IAAIC,uBAAA,CAAa,MAAM,CAAA;AAC5C,EAAA,OAAO,YAAA,CAAa,cAAA,CAAe,MAAA,EAAQ,QAAA,EAAU,MAAM,CAAA;AAC5D;AAIA,WAAA,CAAY,cAAc,CAAA;;"}
@@ -1,8 +1,8 @@
1
1
  'use strict';
2
2
 
3
3
  var vitest = require('vitest');
4
- var matchers = require('./matchers.js');
5
- require('./matcher-utils.js');
4
+ var vitestMatchers = require('./vitest-matchers.js');
5
+ require('./vitest-utils.js');
6
6
  require('./core.js');
7
7
  require('ajv');
8
8
  require('./elements.js');
@@ -21,10 +21,12 @@ require('node:fs/promises');
21
21
  require('node:url');
22
22
 
23
23
  vitest.expect.extend({
24
- toBeValid: matchers.createMatcher$4(),
25
- toBeInvalid: matchers.createMatcher$3(),
26
- toHTMLValidate: matchers.createMatcher$2(vitest.expect, void 0),
27
- toHaveError: matchers.createMatcher$1(vitest.expect, void 0),
28
- toHaveErrors: matchers.createMatcher(vitest.expect, void 0)
24
+ toBeValid: vitestMatchers.createMatcher$6(),
25
+ toBeInvalid: vitestMatchers.createMatcher$5(),
26
+ toHTMLValidate: vitestMatchers.createMatcher$4(vitest.expect),
27
+ toHaveError: vitestMatchers.createMatcher$3(vitest.expect),
28
+ toHaveErrors: vitestMatchers.createMatcher$2(vitest.expect),
29
+ toMatchCodeframe: vitestMatchers.createMatcher$1(),
30
+ toMatchInlineCodeframe: vitestMatchers.createMatcher()
29
31
  });
30
32
  //# sourceMappingURL=vitest.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vitest.js","sources":["../../src/vitest/vitest.ts"],"sourcesContent":["import \"./augmentation\";\n\nimport { expect } from \"vitest\";\nimport {\n\ttoBeInvalid,\n\ttoBeValid,\n\ttoHTMLValidate,\n\ttoHaveError,\n\ttoHaveErrors,\n} from \"../jest/matchers\";\n\nexpect.extend({\n\ttoBeValid: toBeValid(),\n\ttoBeInvalid: toBeInvalid(),\n\ttoHTMLValidate: toHTMLValidate(expect, undefined),\n\ttoHaveError: toHaveError(expect, undefined),\n\ttoHaveErrors: toHaveErrors(expect, undefined),\n});\n"],"names":["expect","toBeValid","toBeInvalid","toHTMLValidate","toHaveError","toHaveErrors"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAWAA,aAAA,CAAO,MAAA,CAAO;AAAA,EACb,WAAWC,wBAAA,EAAU;AAAA,EACrB,aAAaC,wBAAA,EAAY;AAAA,EACzB,cAAA,EAAgBC,wBAAA,CAAeH,aAAA,EAAQ,MAAS,CAAA;AAAA,EAChD,WAAA,EAAaI,wBAAA,CAAYJ,aAAA,EAAQ,MAAS,CAAA;AAAA,EAC1C,YAAA,EAAcK,sBAAA,CAAaL,aAAA,EAAQ,MAAS;AAC7C,CAAC,CAAA;;"}
1
+ {"version":3,"file":"vitest.js","sources":["../../src/vitest/vitest.ts"],"sourcesContent":["import \"./augmentation\";\n\nimport { expect } from \"vitest\";\nimport {\n\ttoBeInvalid,\n\ttoBeValid,\n\ttoHTMLValidate,\n\ttoHaveError,\n\ttoHaveErrors,\n\ttoMatchCodeframe,\n\ttoMatchInlineCodeframe,\n} from \"./matchers\";\n\nexpect.extend({\n\ttoBeValid: toBeValid(),\n\ttoBeInvalid: toBeInvalid(),\n\ttoHTMLValidate: toHTMLValidate(expect),\n\ttoHaveError: toHaveError(expect),\n\ttoHaveErrors: toHaveErrors(expect),\n\ttoMatchCodeframe: toMatchCodeframe(),\n\ttoMatchInlineCodeframe: toMatchInlineCodeframe(),\n});\n"],"names":["expect","toBeValid","toBeInvalid","toHTMLValidate","toHaveError","toHaveErrors","toMatchCodeframe","toMatchInlineCodeframe"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAaAA,aAAA,CAAO,MAAA,CAAO;AAAA,EACb,WAAWC,8BAAA,EAAU;AAAA,EACrB,aAAaC,8BAAA,EAAY;AAAA,EACzB,cAAA,EAAgBC,+BAAeH,aAAM,CAAA;AAAA,EACrC,WAAA,EAAaI,+BAAYJ,aAAM,CAAA;AAAA,EAC/B,YAAA,EAAcK,+BAAaL,aAAM,CAAA;AAAA,EACjC,kBAAkBM,8BAAA,EAAiB;AAAA,EACnC,wBAAwBC,4BAAA;AACzB,CAAC,CAAA;;"}
@@ -1,5 +1,5 @@
1
1
  export { H as HtmlValidate, c as compatibilityCheck, e as esmResolver } from './core-browser.js';
2
- export { A as Attribute, g as Config, f as ConfigError, C as ConfigLoader, D as DOMNode, o as DOMTokenList, p as DOMTree, q as DynamicValue, r as EventHandler, H as HtmlElement, M as MetaCopyableProperty, s as MetaTable, N as NestedError, u as Node, a as Parser, P as PerformanceTracker, R as Reporter, w as ResolvedConfig, x as Rule, y as SchemaValidationError, z as Severity, S as StaticConfigLoader, T as TextClassification, B as TextContent, F as TextNode, U as UserError, W as WrappedError, G as ariaNaming, I as classifyNodeText, J as configPresets, K as defineConfig, L as definePlugin, O as isUserError, Q as keywordPatternMatcher, V as ruleExists, X as sliceLocation, Y as staticResolver, v as version, Z as walk } from './core.js';
2
+ export { A as Attribute, C as Config, a as ConfigError, b as ConfigLoader, D as DOMNode, c as DOMTokenList, d as DOMTree, e as DynamicValue, f as EventHandler, H as HtmlElement, M as MetaCopyableProperty, g as MetaTable, N as NestedError, h as Node, P as Parser, i as PerformanceTracker, R as Reporter, j as ResolvedConfig, k as Rule, S as SchemaValidationError, l as Severity, m as StaticConfigLoader, T as TextClassification, n as TextContent, o as TextNode, U as UserError, W as WrappedError, p as ariaNaming, r as classifyNodeText, X as configPresets, w as defineConfig, x as definePlugin, K as isUserError, O as keywordPatternMatcher, Y as ruleExists, Z as sliceLocation, _ as staticResolver, a3 as version, a5 as walk } from './core.js';
3
3
  export { d as defineMetadata, m as metadataHelper } from './meta-helper.js';
4
4
  import 'ajv';
5
5
  import './elements.js';
package/dist/esm/cli.js CHANGED
@@ -1,12 +1,12 @@
1
1
  import { l as legacyRequire, F as FileSystemConfigLoader, H as HtmlValidate, e as esmResolver } from './core-nodejs.js';
2
- import { U as UserError, j as ensureError, k as getFormatter$1, l as deepmerge, m as ignore, R as Reporter, _ as engines } from './core.js';
2
+ import { U as UserError, z as ensureError, F as getFormatter$1, v as deepmerge, I as ignore, R as Reporter, y as engines } from './core.js';
3
3
  import path$1 from 'node:path/posix';
4
4
  import fs from 'node:fs';
5
5
  import path from 'node:path';
6
- import { globSync } from 'glob';
7
6
  import prompts from 'prompts';
8
7
  import './meta-helper.js';
9
8
  import kleur from 'kleur';
9
+ import { styleText } from 'node:util';
10
10
  import betterAjvErrors from '@sidvind/better-ajv-errors';
11
11
 
12
12
  const DEFAULT_EXTENSIONS = ["html"];
@@ -39,7 +39,7 @@ function expandFiles(patterns, options) {
39
39
  result.push("/dev/stdin");
40
40
  return result;
41
41
  }
42
- for (const filename of globSync(pattern, { cwd })) {
42
+ for (const filename of fs.globSync(pattern, { cwd })) {
43
43
  const fullpath = join(cwd, filename);
44
44
  if (isDirectory(fullpath)) {
45
45
  const dir = expandFiles([directoryPattern(extensions)], { ...options, cwd: fullpath });
@@ -607,7 +607,12 @@ function prettyError(err) {
607
607
  return betterAjvErrors(err.schema, err.obj, err.errors, {
608
608
  format: "cli",
609
609
  indent: 2,
610
- json
610
+ json,
611
+ colors: {
612
+ error: styleText.bind(void 0, "red"),
613
+ property: styleText.bind(void 0, "magenta"),
614
+ bold: styleText.bind(void 0, "bold")
615
+ }
611
616
  });
612
617
  }
613
618
  function handleSchemaValidationError(console, err) {
@@ -649,5 +654,5 @@ function haveImportMetaResolve() {
649
654
  return "resolve" in import.meta;
650
655
  }
651
656
 
652
- export { CLI as C, ImportResolveMissingError as I, Mode as M, handleSchemaValidationError as a, dump as d, haveImportMetaResolve as h, init as i, lint as l, modeToFlag as m, printConfig as p };
657
+ export { CLI as C, ImportResolveMissingError as I, Mode as M, haveImportMetaResolve as a, dump as d, handleSchemaValidationError as h, init as i, lint as l, modeToFlag as m, printConfig as p };
653
658
  //# sourceMappingURL=cli.js.map