agent-comms 9.0.3 → 9.0.4

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 (116) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +4 -0
  4. package/dist/bridges/user/web/test/web-access.unit.test.d.ts +1 -1
  5. package/dist/bridges/user/web/test/web-access.unit.test.js +19 -375
  6. package/dist/bridges/user/web/test/web-access.unit.test.js.map +1 -1
  7. package/dist/core/bridge.d.ts +11 -0
  8. package/dist/core/bridge.d.ts.map +1 -1
  9. package/dist/core/bridge.js +17 -2
  10. package/dist/core/bridge.js.map +1 -1
  11. package/dist/core/index.d.ts +1 -1
  12. package/dist/core/index.d.ts.map +1 -1
  13. package/dist/core/index.js +1 -1
  14. package/dist/core/index.js.map +1 -1
  15. package/dist/core/test/build-action.unit.test.d.ts +2 -0
  16. package/dist/core/test/build-action.unit.test.d.ts.map +1 -0
  17. package/dist/core/test/build-action.unit.test.js +28 -0
  18. package/dist/core/test/build-action.unit.test.js.map +1 -0
  19. package/dist/test/ci-required-checks.unit.test.d.ts +2 -0
  20. package/dist/test/ci-required-checks.unit.test.d.ts.map +1 -0
  21. package/dist/test/ci-required-checks.unit.test.js +137 -0
  22. package/dist/test/ci-required-checks.unit.test.js.map +1 -0
  23. package/dist/test/claude-command.unit.test.js +2 -21
  24. package/dist/test/claude-command.unit.test.js.map +1 -1
  25. package/dist/test/conformance/corpus-files.d.ts +11 -0
  26. package/dist/test/conformance/corpus-files.d.ts.map +1 -0
  27. package/dist/test/conformance/corpus-files.js +71 -0
  28. package/dist/test/conformance/corpus-files.js.map +1 -0
  29. package/dist/test/conformance/corpus-types.d.ts +62 -0
  30. package/dist/test/conformance/corpus-types.d.ts.map +1 -0
  31. package/dist/test/conformance/corpus-types.js +8 -0
  32. package/dist/test/conformance/corpus-types.js.map +1 -0
  33. package/dist/test/conformance/corpus.d.ts +34 -0
  34. package/dist/test/conformance/corpus.d.ts.map +1 -0
  35. package/dist/test/conformance/corpus.js +134 -0
  36. package/dist/test/conformance/corpus.js.map +1 -0
  37. package/dist/test/conformance/read-json.d.ts +2 -0
  38. package/dist/test/conformance/read-json.d.ts.map +1 -0
  39. package/dist/test/conformance/read-json.js +7 -0
  40. package/dist/test/conformance/read-json.js.map +1 -0
  41. package/dist/test/conformance/text.d.ts +10 -0
  42. package/dist/test/conformance/text.d.ts.map +1 -0
  43. package/dist/test/conformance/text.js +64 -0
  44. package/dist/test/conformance/text.js.map +1 -0
  45. package/dist/test/conformance/validate.d.ts +14 -0
  46. package/dist/test/conformance/validate.d.ts.map +1 -0
  47. package/dist/test/conformance/validate.js +85 -0
  48. package/dist/test/conformance/validate.js.map +1 -0
  49. package/dist/test/conformance-functions.helper.d.ts +19 -0
  50. package/dist/test/conformance-functions.helper.d.ts.map +1 -0
  51. package/dist/test/conformance-functions.helper.js +583 -0
  52. package/dist/test/conformance-functions.helper.js.map +1 -0
  53. package/dist/test/conformance.unit.test.d.ts +2 -0
  54. package/dist/test/conformance.unit.test.d.ts.map +1 -0
  55. package/dist/test/conformance.unit.test.js +358 -0
  56. package/dist/test/conformance.unit.test.js.map +1 -0
  57. package/dist/test/error-reporting.unit.test.js +2 -90
  58. package/dist/test/error-reporting.unit.test.js.map +1 -1
  59. package/dist/test/version-report-actions.unit.test.d.ts +1 -1
  60. package/dist/test/version-report-actions.unit.test.js +2 -55
  61. package/dist/test/version-report-actions.unit.test.js.map +1 -1
  62. package/package.json +4 -2
  63. package/src/core/bridge.ts +30 -1
  64. package/src/core/index.ts +1 -0
  65. package/dist/core/test/bridge.unit.test.d.ts +0 -5
  66. package/dist/core/test/bridge.unit.test.d.ts.map +0 -1
  67. package/dist/core/test/bridge.unit.test.js +0 -119
  68. package/dist/core/test/bridge.unit.test.js.map +0 -1
  69. package/dist/test/agent-table.unit.test.d.ts +0 -5
  70. package/dist/test/agent-table.unit.test.d.ts.map +0 -1
  71. package/dist/test/agent-table.unit.test.js +0 -53
  72. package/dist/test/agent-table.unit.test.js.map +0 -1
  73. package/dist/test/bind-retry.unit.test.d.ts +0 -2
  74. package/dist/test/bind-retry.unit.test.d.ts.map +0 -1
  75. package/dist/test/bind-retry.unit.test.js +0 -42
  76. package/dist/test/bind-retry.unit.test.js.map +0 -1
  77. package/dist/test/default-command.unit.test.d.ts +0 -2
  78. package/dist/test/default-command.unit.test.d.ts.map +0 -1
  79. package/dist/test/default-command.unit.test.js +0 -26
  80. package/dist/test/default-command.unit.test.js.map +0 -1
  81. package/dist/test/delegation-policy.unit.test.d.ts +0 -5
  82. package/dist/test/delegation-policy.unit.test.d.ts.map +0 -1
  83. package/dist/test/delegation-policy.unit.test.js +0 -52
  84. package/dist/test/delegation-policy.unit.test.js.map +0 -1
  85. package/dist/test/display-name.unit.test.d.ts +0 -5
  86. package/dist/test/display-name.unit.test.d.ts.map +0 -1
  87. package/dist/test/display-name.unit.test.js +0 -65
  88. package/dist/test/display-name.unit.test.js.map +0 -1
  89. package/dist/test/machine-list-groups.unit.test.d.ts +0 -5
  90. package/dist/test/machine-list-groups.unit.test.d.ts.map +0 -1
  91. package/dist/test/machine-list-groups.unit.test.js +0 -61
  92. package/dist/test/machine-list-groups.unit.test.js.map +0 -1
  93. package/dist/test/relay-selection.unit.test.d.ts +0 -5
  94. package/dist/test/relay-selection.unit.test.d.ts.map +0 -1
  95. package/dist/test/relay-selection.unit.test.js +0 -103
  96. package/dist/test/relay-selection.unit.test.js.map +0 -1
  97. package/dist/test/request-timeouts.unit.test.d.ts +0 -2
  98. package/dist/test/request-timeouts.unit.test.d.ts.map +0 -1
  99. package/dist/test/request-timeouts.unit.test.js +0 -28
  100. package/dist/test/request-timeouts.unit.test.js.map +0 -1
  101. package/dist/test/room-discovery.unit.test.d.ts +0 -2
  102. package/dist/test/room-discovery.unit.test.d.ts.map +0 -1
  103. package/dist/test/room-discovery.unit.test.js +0 -29
  104. package/dist/test/room-discovery.unit.test.js.map +0 -1
  105. package/dist/test/room-lookup.unit.test.d.ts +0 -2
  106. package/dist/test/room-lookup.unit.test.d.ts.map +0 -1
  107. package/dist/test/room-lookup.unit.test.js +0 -59
  108. package/dist/test/room-lookup.unit.test.js.map +0 -1
  109. package/dist/test/room-path.unit.test.d.ts +0 -2
  110. package/dist/test/room-path.unit.test.d.ts.map +0 -1
  111. package/dist/test/room-path.unit.test.js +0 -54
  112. package/dist/test/room-path.unit.test.js.map +0 -1
  113. package/dist/test/send-outcome.unit.test.d.ts +0 -2
  114. package/dist/test/send-outcome.unit.test.d.ts.map +0 -1
  115. package/dist/test/send-outcome.unit.test.js +0 -52
  116. package/dist/test/send-outcome.unit.test.js.map +0 -1
@@ -0,0 +1,134 @@
1
+ import { join } from "node:path";
2
+ import { selectCorpusFiles } from "./corpus-files.js";
3
+ import { readJson } from "./read-json.js";
4
+ import { validateCorpusFile, validateManifest } from "./validate.js";
5
+ /** What the files of a corpus say about themselves, in the manifest's own shape. */
6
+ function describeFiles(files) {
7
+ return Object.fromEntries(files.map(({ name, file }) => [
8
+ name,
9
+ JSON.stringify({
10
+ cases: file.cases.length,
11
+ skip: file.cases
12
+ .filter((testCase) => testCase.skip !== undefined)
13
+ .map((testCase) => testCase.id)
14
+ .sort(),
15
+ }),
16
+ ]));
17
+ }
18
+ /** The case ids this implementation registers to run and the ones it skips because they are marked for it alone. A case marked for the other implementation is registered and run here. */
19
+ export function collect(files) {
20
+ const cases = files.flatMap(({ file }) => file.cases);
21
+ return {
22
+ registered: cases.filter(({ skip }) => skip !== "ts").map(({ id }) => id),
23
+ skipped: cases.filter(({ skip }) => skip === "ts").map(({ id }) => id),
24
+ };
25
+ }
26
+ /**
27
+ * The completeness check, per implementation: what this implementation registered and skipped must add up to the manifest's total, and what it skips must be marked in the manifest. Cases marked for the other implementation count as registered here, so they cannot fail it.
28
+ */
29
+ export function completenessProblems(total, markedIds, registered, skipped) {
30
+ const problems = [];
31
+ if (registered.length + skipped.length !== total) {
32
+ problems.push(`registered ${String(registered.length)} plus skipped ${String(skipped.length)} is not the manifest's ${String(total)}`);
33
+ }
34
+ for (const id of skipped) {
35
+ if (!markedIds.has(id)) {
36
+ problems.push(`${id} is skipped here and not marked in the manifest`);
37
+ }
38
+ }
39
+ if (new Set([...registered, ...skipped]).size !==
40
+ registered.length + skipped.length) {
41
+ problems.push("a case is both registered and skipped, or registered twice");
42
+ }
43
+ return problems;
44
+ }
45
+ export function checkCorpus(root) {
46
+ const selection = selectCorpusFiles(root);
47
+ const problems = selection.problems.map((path) => `${path}: not a corpus file and not a recognised root file`);
48
+ const files = [];
49
+ const ids = new Set();
50
+ for (const name of selection.selected) {
51
+ const result = validateCorpusFile(readJson(join(root, name)));
52
+ if (!result.ok) {
53
+ problems.push(...result.problems.map((problem) => `${name}: ${problem}`));
54
+ continue;
55
+ }
56
+ const directory = name.slice(0, name.indexOf("/"));
57
+ for (const { id, kind } of result.value.cases) {
58
+ if (kind !== directory) {
59
+ problems.push(`${name}: case ${id} is of kind ${kind}, and the directory names kind ${directory}`);
60
+ }
61
+ if (ids.has(id)) {
62
+ problems.push(`${name}: case id ${id} is used by another file`);
63
+ }
64
+ ids.add(id);
65
+ }
66
+ files.push({ name, file: result.value });
67
+ }
68
+ let manifest;
69
+ try {
70
+ manifest = validateManifest(readJson(join(root, "manifest.json")));
71
+ }
72
+ catch (error) {
73
+ manifest = {
74
+ ok: false,
75
+ problems: [error instanceof Error ? error.message : String(error)],
76
+ };
77
+ }
78
+ if (!manifest.ok) {
79
+ problems.push(...manifest.problems.map((problem) => `manifest.json: ${problem}`));
80
+ }
81
+ else {
82
+ const recorded = Object.fromEntries(Object.entries(manifest.value.files).map(([name, entry]) => [
83
+ name,
84
+ JSON.stringify({ cases: entry.cases, skip: entry.skip }),
85
+ ]));
86
+ const actual = describeFiles(files);
87
+ const counts = collect(files);
88
+ problems.push(...completenessProblems(Object.values(manifest.value.files).reduce((sum, entry) => sum + entry.cases, 0), new Set(Object.values(manifest.value.files).flatMap((entry) => entry.skip)), counts.registered, counts.skipped));
89
+ for (const name of new Set([
90
+ ...Object.keys(recorded),
91
+ ...Object.keys(actual),
92
+ ])) {
93
+ if (recorded[name] !== actual[name]) {
94
+ problems.push(`manifest.json does not match ${name}: the file holds ${actual[name] ?? "nothing"}, the manifest records ${recorded[name] ?? "nothing"}`);
95
+ }
96
+ }
97
+ }
98
+ return { files, problems };
99
+ }
100
+ /**
101
+ * What a run did, against what the manifest says the corpus holds: every file has as many registrations as the manifest has cases, the cases this implementation skips are the ones carrying `skip: ts` and are listed in the manifest, and every other registration ran. `registrations` is filled where the runner registers each case and `ran` where each registered case's body starts, so a runner that skips, filters or mis-keys cases reads as a failure here, and the corpus alone cannot make it pass.
102
+ */
103
+ export function runCompletenessProblems(manifest, registrations, ran) {
104
+ const problems = [];
105
+ const perFile = new Map();
106
+ const seen = new Set();
107
+ for (const { file, id, skip } of registrations) {
108
+ perFile.set(file, (perFile.get(file) ?? 0) + 1);
109
+ if (seen.has(id)) {
110
+ problems.push(`${id} was registered twice`);
111
+ }
112
+ seen.add(id);
113
+ const entry = manifest.files[file];
114
+ if (skip === "ts" && entry?.skip.includes(id) !== true) {
115
+ problems.push(`${id} is skipped here and not listed in the manifest`);
116
+ }
117
+ if (skip !== "ts" && !ran.has(id)) {
118
+ problems.push(`${id} was registered and did not run`);
119
+ }
120
+ }
121
+ for (const [file, entry] of Object.entries(manifest.files)) {
122
+ const count = perFile.get(file) ?? 0;
123
+ if (count !== entry.cases) {
124
+ problems.push(`${file}: ${String(count)} cases registered, the manifest has ${String(entry.cases)}`);
125
+ }
126
+ }
127
+ for (const file of perFile.keys()) {
128
+ if (!(file in manifest.files)) {
129
+ problems.push(`${file} was registered and is not in the manifest`);
130
+ }
131
+ }
132
+ return problems;
133
+ }
134
+ //# sourceMappingURL=corpus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus.js","sourceRoot":"","sources":["../../../src/test/conformance/corpus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function readJson(path: string): unknown;
2
+ //# sourceMappingURL=read-json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-json.d.ts","sourceRoot":"","sources":["../../../src/test/conformance/read-json.ts"],"names":[],"mappings":"AAKA,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE9C"}
@@ -0,0 +1,7 @@
1
+ import { readFileSync } from "node:fs";
2
+ /** Strict: a file that is not valid UTF-8 is an error, never read with replacement characters, and a leading byte order mark is kept and so refused by the parse, so every loader sees the same text (the Rust loader refuses both too). */
3
+ const decoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
4
+ export function readJson(path) {
5
+ return JSON.parse(decoder.decode(readFileSync(path)));
6
+ }
7
+ //# sourceMappingURL=read-json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read-json.js","sourceRoot":"","sources":["../../../src/test/conformance/read-json.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC,4OAA4O;AAC5O,MAAM,OAAO,GAAG,IAAI,WAAW,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAE3E,MAAM,UAAU,QAAQ,CAAC,IAAY;IACnC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACxD,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { Text } from "./corpus-types.js";
2
+ /** The string a corpus text denotes. */
3
+ export declare function textToString(text: Text): string;
4
+ /** The UTF-16 code units a corpus text denotes. */
5
+ export declare function textToCodeUnits(text: Text): readonly number[];
6
+ /** The name of a special number, as a corpus file writes it, or undefined for any other number. */
7
+ export declare function specialNumberName(value: number): string | undefined;
8
+ /** A value with every `{ "codeUnits": [...] }` replaced by the string it denotes and every `{ "$number": name }` by the number it names, at any depth. The schema has already refused an object that holds either key and anything else. */
9
+ export declare function decodeValue(value: unknown): unknown;
10
+ //# sourceMappingURL=text.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/test/conformance/text.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAkB9C,wCAAwC;AACxC,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM,CAI/C;AAED,mDAAmD;AACnD,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,MAAM,EAAE,CAQ7D;AAUD,mGAAmG;AACnG,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOnE;AAED,4OAA4O;AAC5O,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAwBnD"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * The corpus carries every string as a sequence of UTF-16 code units, either as a JSON string or as `{ "codeUnits": [...] }` (`conformance/README.md`). A JavaScript string is already that sequence, so decoding is the identity for the first form and `String.fromCharCode` for the second.
3
+ */
4
+ function isRecord(value) {
5
+ return typeof value === "object" && value !== null && !Array.isArray(value);
6
+ }
7
+ function isCodeUnitsObject(value) {
8
+ const units = value.codeUnits;
9
+ return Array.isArray(units) && units.every((u) => typeof u === "number");
10
+ }
11
+ /** The string a corpus text denotes. */
12
+ export function textToString(text) {
13
+ return typeof text === "string"
14
+ ? text
15
+ : String.fromCharCode(...text.codeUnits);
16
+ }
17
+ /** The UTF-16 code units a corpus text denotes. */
18
+ export function textToCodeUnits(text) {
19
+ if (typeof text !== "string") {
20
+ return text.codeUnits;
21
+ }
22
+ return Array.from({ length: text.length }, (_, index) => text.charCodeAt(index));
23
+ }
24
+ /** The numbers a corpus file names with `{ "$number": name }`, a closed lookup: the canonical JSON form writes a negative zero as 0 and has no infinity or NaN. */
25
+ const NAMED_NUMBERS = {
26
+ "-0": -0,
27
+ Infinity: Number.POSITIVE_INFINITY,
28
+ "-Infinity": Number.NEGATIVE_INFINITY,
29
+ NaN: Number.NaN,
30
+ };
31
+ /** The name of a special number, as a corpus file writes it, or undefined for any other number. */
32
+ export function specialNumberName(value) {
33
+ if (Number.isNaN(value))
34
+ return "NaN";
35
+ if (Object.is(value, -0))
36
+ return "-0";
37
+ if (value === Number.POSITIVE_INFINITY)
38
+ return "Infinity";
39
+ if (value === Number.NEGATIVE_INFINITY)
40
+ return "-Infinity";
41
+ return undefined;
42
+ }
43
+ /** A value with every `{ "codeUnits": [...] }` replaced by the string it denotes and every `{ "$number": name }` by the number it names, at any depth. The schema has already refused an object that holds either key and anything else. */
44
+ export function decodeValue(value) {
45
+ if (Array.isArray(value)) {
46
+ return value.map((item) => decodeValue(item));
47
+ }
48
+ if (isRecord(value)) {
49
+ const named = value.$number;
50
+ if (typeof named === "string" && Object.keys(value).length === 1) {
51
+ const decoded = NAMED_NUMBERS[named];
52
+ if (decoded === undefined) {
53
+ throw new Error(`$number names ${named}, which no corpus file may`);
54
+ }
55
+ return decoded;
56
+ }
57
+ if (isCodeUnitsObject(value)) {
58
+ return String.fromCharCode(...value.codeUnits);
59
+ }
60
+ return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, decodeValue(item)]));
61
+ }
62
+ return value;
63
+ }
64
+ //# sourceMappingURL=text.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"text.js","sourceRoot":"","sources":["../../../src/test/conformance/text.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import type { CorpusFile, Manifest } from "./corpus-types.js";
2
+ /**
3
+ * Validates corpus files and the manifest against the schemas in `conformance/`, which is the whole definition of the format. The checks beside the schema are the rules JSON Schema cannot express and `conformance/README.md` lists: a case id is not repeated within a file, a manifest's `skip` lists are in ascending order, and no JSON string holds an unpaired surrogate (content that needs one is written as `{ "codeUnits": [...] }`). Nothing else is validated by hand.
4
+ */
5
+ export type Validation<T> = {
6
+ readonly ok: true;
7
+ readonly value: T;
8
+ } | {
9
+ readonly ok: false;
10
+ readonly problems: readonly string[];
11
+ };
12
+ export declare function validateCorpusFile(value: unknown): Validation<CorpusFile>;
13
+ export declare function validateManifest(value: unknown): Validation<Manifest>;
14
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/test/conformance/validate.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAE9D;;GAEG;AAEH,MAAM,MAAM,UAAU,CAAC,CAAC,IACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACxC;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,CAAC;AAgFjE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAAC,UAAU,CAAC,CAWzE;AAWD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAAC,QAAQ,CAAC,CAWrE"}
@@ -0,0 +1,85 @@
1
+ import { readFileSync } from "node:fs";
2
+ import { fileURLToPath } from "node:url";
3
+ import Ajv2020Module from "ajv/dist/2020.js";
4
+ function readSchema(name) {
5
+ const parsed = JSON.parse(readFileSync(fileURLToPath(new URL(`../../../conformance/${name}`, import.meta.url)), "utf8"));
6
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
7
+ throw new Error(`${name} must hold a JSON object`);
8
+ }
9
+ return Object.fromEntries(Object.entries(parsed));
10
+ }
11
+ // Strict mode, so a schema keyword Ajv does not know is an error rather than ignored; unions of types are what the schema's open "any JSON value" definitions use.
12
+ // ajv ships CommonJS with a default export, which Node16 resolution types as the module and not the class.
13
+ const Ajv2020 = Ajv2020Module.default;
14
+ const ajv = new Ajv2020({
15
+ allErrors: true,
16
+ strict: true,
17
+ allowUnionTypes: true,
18
+ });
19
+ // The generic states what a document the schema accepted holds; it is the schema, not this code, that makes it true.
20
+ const checkCorpusFile = ajv.compile(readSchema("case.schema.json"));
21
+ const checkManifest = ajv.compile(readSchema("manifest.schema.json"));
22
+ function describeErrors(errors) {
23
+ if (errors === null || errors === undefined) {
24
+ return ["the schema rejected the document"];
25
+ }
26
+ return errors.map(({ instancePath, message }) => `${instancePath === "" ? "(root)" : instancePath} ${message ?? "is invalid"}`);
27
+ }
28
+ function isRecord(value) {
29
+ return typeof value === "object" && value !== null && !Array.isArray(value);
30
+ }
31
+ /** Where a JSON string, or an object key, holds an unpaired surrogate: such a document is read differently by different loaders. */
32
+ function malformedStrings(value, where) {
33
+ if (typeof value === "string") {
34
+ return value.isWellFormed() ? [] : [`${where} holds an unpaired surrogate`];
35
+ }
36
+ if (Array.isArray(value)) {
37
+ return value.flatMap((item, index) => malformedStrings(item, `${where}/${String(index)}`));
38
+ }
39
+ if (isRecord(value)) {
40
+ return Object.entries(value).flatMap(([key, item]) => [
41
+ ...malformedStrings(key, `${where}/(key)`),
42
+ ...malformedStrings(item, `${where}/${key}`),
43
+ ]);
44
+ }
45
+ return [];
46
+ }
47
+ function ruleProblems(file) {
48
+ const problems = [];
49
+ const ids = new Set();
50
+ for (const testCase of file.cases) {
51
+ if (ids.has(testCase.id)) {
52
+ problems.push(`case id ${testCase.id} is used twice in the file`);
53
+ }
54
+ ids.add(testCase.id);
55
+ }
56
+ return problems;
57
+ }
58
+ export function validateCorpusFile(value) {
59
+ const malformed = malformedStrings(value, "");
60
+ if (malformed.length > 0) {
61
+ return { ok: false, problems: malformed };
62
+ }
63
+ if (!checkCorpusFile(value)) {
64
+ return { ok: false, problems: describeErrors(checkCorpusFile.errors) };
65
+ }
66
+ const problems = ruleProblems(value);
67
+ return problems.length === 0 ? { ok: true, value } : { ok: false, problems };
68
+ }
69
+ /** Whether the ids are distinct and in ascending UTF-16 code unit order, which is the order every loader sorts in for the ASCII ids the schema allows. */
70
+ function isAscending(ids) {
71
+ return ids.every((id, index) => {
72
+ const before = ids[index - 1];
73
+ return before === undefined || before < id;
74
+ });
75
+ }
76
+ export function validateManifest(value) {
77
+ if (!checkManifest(value)) {
78
+ return { ok: false, problems: describeErrors(checkManifest.errors) };
79
+ }
80
+ const problems = Object.entries(value.files).flatMap(([name, entry]) => isAscending(entry.skip)
81
+ ? []
82
+ : [`${name}: "skip" must list distinct ids in ascending order`]);
83
+ return problems.length === 0 ? { ok: true, value } : { ok: false, problems };
84
+ }
85
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/test/conformance/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ type CorpusFunction = (...args: readonly unknown[]) => unknown;
2
+ /** The outcome of validating an input: what the schema made of it, or every issue it found. */
3
+ export type ValidateResult = {
4
+ readonly ok: true;
5
+ readonly value: unknown;
6
+ } | {
7
+ readonly ok: false;
8
+ readonly issues: readonly {
9
+ readonly path: readonly (string | number)[];
10
+ readonly code: string;
11
+ readonly message: string;
12
+ }[];
13
+ };
14
+ export declare const FUNCTIONS: Readonly<Record<string, CorpusFunction>>;
15
+ export declare const SCHEMAS: Readonly<Record<string, (input: unknown) => ValidateResult>>;
16
+ /** Exposed for the CommsError code check the runner makes on a `throws` expectation. */
17
+ export declare function errorCode(error: unknown): string | undefined;
18
+ export {};
19
+ //# sourceMappingURL=conformance-functions.helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conformance-functions.helper.d.ts","sourceRoot":"","sources":["../../src/test/conformance-functions.helper.ts"],"names":[],"mappings":"AAwGA,KAAK,cAAc,GAAG,CAAC,GAAG,IAAI,EAAE,SAAS,OAAO,EAAE,KAAK,OAAO,CAAC;AAE/D,+FAA+F;AAC/F,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAC9C;IACE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IACnB,QAAQ,CAAC,MAAM,EAAE,SAAS;QACxB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;QAC5C,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1B,EAAE,CAAC;CACL,CAAC;AAuZN,eAAO,MAAM,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAqS9D,CAAC;AAqBF,eAAO,MAAM,OAAO,EAAE,QAAQ,CAC5B,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,cAAc,CAAC,CAgBnD,CAAC;AAEF,wFAAwF;AACxF,wBAAgB,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE5D"}