@interop/was-conformance-suite 0.1.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 (91) hide show
  1. package/LICENSE.md +20 -0
  2. package/README.md +264 -0
  3. package/dist/cli/index.d.ts +3 -0
  4. package/dist/cli/index.d.ts.map +1 -0
  5. package/dist/cli/index.js +69 -0
  6. package/dist/cli/index.js.map +1 -0
  7. package/dist/cli/main.d.ts +64 -0
  8. package/dist/cli/main.d.ts.map +1 -0
  9. package/dist/cli/main.js +294 -0
  10. package/dist/cli/main.js.map +1 -0
  11. package/dist/cli/reporters/json.d.ts +32 -0
  12. package/dist/cli/reporters/json.d.ts.map +1 -0
  13. package/dist/cli/reporters/json.js +30 -0
  14. package/dist/cli/reporters/json.js.map +1 -0
  15. package/dist/cli/reporters/pretty.d.ts +21 -0
  16. package/dist/cli/reporters/pretty.d.ts.map +1 -0
  17. package/dist/cli/reporters/pretty.js +152 -0
  18. package/dist/cli/reporters/pretty.js.map +1 -0
  19. package/dist/harness/assert.d.ts +13 -0
  20. package/dist/harness/assert.d.ts.map +1 -0
  21. package/dist/harness/assert.js +13 -0
  22. package/dist/harness/assert.js.map +1 -0
  23. package/dist/harness/runner.d.ts +25 -0
  24. package/dist/harness/runner.d.ts.map +1 -0
  25. package/dist/harness/runner.js +240 -0
  26. package/dist/harness/runner.js.map +1 -0
  27. package/dist/harness/types.d.ts +199 -0
  28. package/dist/harness/types.d.ts.map +1 -0
  29. package/dist/harness/types.js +2 -0
  30. package/dist/harness/types.js.map +1 -0
  31. package/dist/helpers.d.ts +103 -0
  32. package/dist/helpers.d.ts.map +1 -0
  33. package/dist/helpers.js +195 -0
  34. package/dist/helpers.js.map +1 -0
  35. package/dist/index.d.ts +28 -0
  36. package/dist/index.d.ts.map +1 -0
  37. package/dist/index.js +35 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/suites/changes-query-api.d.ts +9 -0
  40. package/dist/suites/changes-query-api.d.ts.map +1 -0
  41. package/dist/suites/changes-query-api.js +115 -0
  42. package/dist/suites/changes-query-api.js.map +1 -0
  43. package/dist/suites/client-backends.d.ts +11 -0
  44. package/dist/suites/client-backends.d.ts.map +1 -0
  45. package/dist/suites/client-backends.js +198 -0
  46. package/dist/suites/client-backends.js.map +1 -0
  47. package/dist/suites/client-delegation.d.ts +21 -0
  48. package/dist/suites/client-delegation.d.ts.map +1 -0
  49. package/dist/suites/client-delegation.js +94 -0
  50. package/dist/suites/client-delegation.js.map +1 -0
  51. package/dist/suites/client-export-import.d.ts +19 -0
  52. package/dist/suites/client-export-import.d.ts.map +1 -0
  53. package/dist/suites/client-export-import.js +74 -0
  54. package/dist/suites/client-export-import.js.map +1 -0
  55. package/dist/suites/client-resources.d.ts +11 -0
  56. package/dist/suites/client-resources.d.ts.map +1 -0
  57. package/dist/suites/client-resources.js +193 -0
  58. package/dist/suites/client-resources.js.map +1 -0
  59. package/dist/suites/client-spaces.d.ts +11 -0
  60. package/dist/suites/client-spaces.d.ts.map +1 -0
  61. package/dist/suites/client-spaces.js +347 -0
  62. package/dist/suites/client-spaces.js.map +1 -0
  63. package/dist/suites/collection-api.d.ts +7 -0
  64. package/dist/suites/collection-api.d.ts.map +1 -0
  65. package/dist/suites/collection-api.js +266 -0
  66. package/dist/suites/collection-api.js.map +1 -0
  67. package/dist/suites/encryption-marker-api.d.ts +9 -0
  68. package/dist/suites/encryption-marker-api.d.ts.map +1 -0
  69. package/dist/suites/encryption-marker-api.js +266 -0
  70. package/dist/suites/encryption-marker-api.js.map +1 -0
  71. package/dist/suites/index.d.ts +23 -0
  72. package/dist/suites/index.d.ts.map +1 -0
  73. package/dist/suites/index.js +32 -0
  74. package/dist/suites/index.js.map +1 -0
  75. package/dist/suites/policy-api.d.ts +12 -0
  76. package/dist/suites/policy-api.d.ts.map +1 -0
  77. package/dist/suites/policy-api.js +187 -0
  78. package/dist/suites/policy-api.js.map +1 -0
  79. package/dist/suites/resource-api.d.ts +8 -0
  80. package/dist/suites/resource-api.d.ts.map +1 -0
  81. package/dist/suites/resource-api.js +393 -0
  82. package/dist/suites/resource-api.js.map +1 -0
  83. package/dist/suites/server.d.ts +3 -0
  84. package/dist/suites/server.d.ts.map +1 -0
  85. package/dist/suites/server.js +25 -0
  86. package/dist/suites/server.js.map +1 -0
  87. package/dist/suites/spaces-api.d.ts +11 -0
  88. package/dist/suites/spaces-api.d.ts.map +1 -0
  89. package/dist/suites/spaces-api.js +411 -0
  90. package/dist/suites/spaces-api.js.map +1 -0
  91. package/package.json +93 -0
package/LICENSE.md ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Interop Alliance
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,264 @@
1
+ # WAS Conformance Suite _(@interop/was-conformance-suite)_
2
+
3
+ [![Node.js CI](https://github.com/interop-alliance/was-conformance-suite/workflows/CI/badge.svg)](https://github.com/interop-alliance/was-conformance-suite/actions?query=workflow%3A%22CI%22)
4
+ [![NPM Version](https://img.shields.io/npm/v/@interop/was-conformance-suite.svg)](https://npm.im/@interop/was-conformance-suite)
5
+
6
+ > Conformance test suite for
7
+ > [Wallet Attached Storage (WAS)](https://digitalcredentials.github.io/wallet-attached-storage-spec/)
8
+ > servers, runnable as a CLI, in the browser, or as a library.
9
+
10
+ ## Table of Contents
11
+
12
+ - [Background](#background)
13
+ - [Security](#security)
14
+ - [Install](#install)
15
+ - [Usage](#usage)
16
+ - [CLI](#cli)
17
+ - [Web app](#web-app)
18
+ - [Programmatic API](#programmatic-api)
19
+ - [Onboarding token](#onboarding-token)
20
+ - [Optional vs required tests](#optional-vs-required-tests)
21
+ - [Adding a test](#adding-a-test)
22
+ - [Contribute](#contribute)
23
+ - [License](#license)
24
+
25
+ ## Background
26
+
27
+ This suite black-box tests any running Wallet Attached Storage server
28
+ implementation over HTTP: spaces, collections, resources, access-control
29
+ policies, change queries, encryption markers, ZCap delegation, and space
30
+ export/import. It never inspects server internals -- point it at a server URL
31
+ (plus an optional onboarding token, if the server gates provisioning) and it
32
+ reports per-test pass/fail results against the
33
+ [WAS spec](https://digitalcredentials.github.io/wallet-attached-storage-spec/).
34
+
35
+ ### The server URL must be byte-identical everywhere
36
+
37
+ ZCap authorization embeds the invocation target URL (including host and port) in
38
+ signed capabilities, and servers verify it as an exact string match. The URL you
39
+ point this suite at must therefore be **byte-identical** to the URL the server
40
+ believes it is serving on (e.g. its `SERVER_URL` setting). In particular,
41
+ `http://localhost:3002` and `http://127.0.0.1:3002` are _not_ interchangeable --
42
+ a mismatch makes the delegated-access tests fail with 404s even though the
43
+ server is otherwise reachable.
44
+
45
+ ## Security
46
+
47
+ The suite uses hardcoded, publicly known did:key test seeds (deterministic test
48
+ identities for its "alice"/"bob" actors). Never authorize these identities on a
49
+ production server. Onboarding tokens are only sent as `Authorization: Bearer`
50
+ headers to the server under test.
51
+
52
+ ## Install
53
+
54
+ - Node.js 24+ is recommended.
55
+
56
+ ### PNPM
57
+
58
+ To install via PNPM:
59
+
60
+ ```
61
+ pnpm install @interop/was-conformance-suite
62
+ ```
63
+
64
+ ### Development
65
+
66
+ To install locally (for development):
67
+
68
+ ```
69
+ git clone https://github.com/interop-alliance/was-conformance-suite.git
70
+ cd was-conformance-suite
71
+ pnpm install
72
+ ```
73
+
74
+ ## Usage
75
+
76
+ The suite runs the same test registry three ways: from the command line, from a
77
+ hosted web app, or as a library. In every case you provide a WAS server URL and,
78
+ if the server gates provisioning, an [onboarding token](#onboarding-token).
79
+
80
+ Remember the
81
+ [byte-identical URL constraint](#the-server-url-must-be-byte-identical-everywhere):
82
+ the server URL you pass must exactly match the URL the server is configured to
83
+ serve on.
84
+
85
+ ### CLI
86
+
87
+ The package ships a single `was-conformance` bin, so you can run it directly
88
+ with `npx` (no install step needed):
89
+
90
+ ```
91
+ npx @interop/was-conformance-suite http://localhost:3002
92
+ ```
93
+
94
+ Or, once installed:
95
+
96
+ ```
97
+ was-conformance http://localhost:3002
98
+ ```
99
+
100
+ Options:
101
+
102
+ ```
103
+ Usage: was-conformance <server-url> [options]
104
+
105
+ Runs the WAS conformance suite against a running server.
106
+ <server-url> falls back to the TEST_SERVER_URL environment variable.
107
+
108
+ Options:
109
+ -t, --token <token> onboarding token (or TEST_ONBOARDING_TOKEN)
110
+ -s, --suite <id> run only the named suite(s), repeatable
111
+ -g, --grep <pattern> filter tests by name
112
+ --include-optional treat optional tests as required (default: run
113
+ them but report as warnings)
114
+ --skip-optional do not run optional tests at all
115
+ -r, --reporter <name> pretty (default) | json
116
+ --timeout <ms> per-test timeout
117
+ --fail-fast stop on first failure
118
+ -h, --help show this help and exit
119
+ -V, --version print the version and exit
120
+ ```
121
+
122
+ The available suite ids (for `--suite`) are:
123
+
124
+ | id | tests |
125
+ | ----------------------- | -------------------------------------- |
126
+ | `changes-query-api` | Collection changes query profile |
127
+ | `client-backends` | WasClient -- BYOS backend registration |
128
+ | `client-delegation` | WasClient -- Delegation |
129
+ | `client-export-import` | WasClient -- Export / Import |
130
+ | `client-resources` | WasClient -- Resources |
131
+ | `client-spaces` | WasClient -- Spaces & Collections |
132
+ | `collection-api` | Collections API |
133
+ | `encryption-marker-api` | Encryption marker API |
134
+ | `policy-api` | Access-control policy API |
135
+ | `resource-api` | Resource API |
136
+ | `server` | Server |
137
+ | `spaces-api` | Spaces |
138
+
139
+ #### Environment-variable fallbacks
140
+
141
+ Two settings can be supplied via the environment instead of on the command line:
142
+
143
+ - `TEST_SERVER_URL` -- used when the `<server-url>` positional is omitted.
144
+ - `TEST_ONBOARDING_TOKEN` -- used when `--token` is omitted.
145
+
146
+ ```
147
+ TEST_SERVER_URL=http://localhost:3002 TEST_ONBOARDING_TOKEN=secret was-conformance
148
+ ```
149
+
150
+ #### Exit codes
151
+
152
+ - `0` -- all required tests passed.
153
+ - `1` -- one or more conformance (required-test) failures.
154
+ - `2` -- usage error, or the server could not be reached.
155
+
156
+ Optional-test failures do not affect the exit code unless `--include-optional`
157
+ promotes them (see [below](#optional-vs-required-tests)).
158
+
159
+ #### JSON reporter for CI
160
+
161
+ For machine-readable output, use the JSON reporter:
162
+
163
+ ```
164
+ was-conformance http://localhost:3002 --reporter json
165
+ ```
166
+
167
+ It writes a structured report to stdout while preserving the same exit-code
168
+ semantics, so a CI job can both assert on the exit code and archive the report.
169
+
170
+ ### Web app
171
+
172
+ A hosted runner is available at
173
+ <https://interop-alliance.github.io/was-conformance-suite/>. Paste in a server
174
+ URL and an optional onboarding token, and the suite runs **fully client-side in
175
+ your browser** -- the token is used only to talk to the server under test and
176
+ never leaves the browser.
177
+
178
+ Because the run happens in the browser, the server under test must allow
179
+ [CORS](https://developer.mozilla.org/docs/Web/HTTP/CORS) from the web app's
180
+ origin. If a run is diagnosed as "server unreachable from a browser (network or
181
+ CORS)", use the [CLI](#cli) instead, which is not subject to browser CORS
182
+ restrictions.
183
+
184
+ You can prefill the server URL field with the `?server=` query parameter, e.g.
185
+ `.../was-conformance-suite/?server=http://localhost:3002`.
186
+
187
+ To run the web app locally during development:
188
+
189
+ ```
190
+ pnpm web:dev
191
+ ```
192
+
193
+ ### Programmatic API
194
+
195
+ Import `runConformance` (and, if you want to select a subset, `suites`) and read
196
+ the returned `RunReport`:
197
+
198
+ ```ts
199
+ import { runConformance, suites } from '@interop/was-conformance-suite'
200
+
201
+ const report = await runConformance({
202
+ serverUrl: 'http://localhost:3002',
203
+ onboardingToken: 'secret', // omit or null if provisioning is open
204
+ suites, // optional: defaults to the full registry
205
+ onEvent: event => {
206
+ if (event.type === 'test-end') {
207
+ console.log(event.result.status, event.result.name)
208
+ }
209
+ }
210
+ })
211
+
212
+ console.log(`conformant: ${report.conformant}`)
213
+ console.log(report.counts) // { total, pass, fail, skip, optionalFail }
214
+ ```
215
+
216
+ `report.conformant` is `true` when no required test failed. See
217
+ [`src/harness/types.ts`](src/harness/types.ts) for the full `RunReport`,
218
+ `RunEvent`, and `TestResult` shapes.
219
+
220
+ ### Onboarding token
221
+
222
+ Some WAS servers gate space provisioning behind a shared-secret onboarding
223
+ token. When configured, the suite sends it as an `Authorization: Bearer` header
224
+ on provisioning requests. If a server does not gate provisioning, space creation
225
+ is open and no token is needed -- omit `--token` / `TEST_ONBOARDING_TOKEN` and
226
+ the `onboardingToken` option.
227
+
228
+ ### Optional vs required tests
229
+
230
+ Some tests are tagged **optional**: they reflect reference-server-flavored
231
+ behavior that is not clearly mandated by the spec. By default optional tests
232
+ still run, but their failures are reported as warnings and do **not** affect the
233
+ exit code. Two flags change this:
234
+
235
+ - `--include-optional` promotes optional tests to required, so their failures
236
+ count toward the exit code.
237
+ - `--skip-optional` does not run optional tests at all.
238
+
239
+ ### Adding a test
240
+
241
+ Tests live in `src/suites/*.ts` as plain data. A suite is a `Suite` object with
242
+ an array of `TestCase` entries; each test has:
243
+
244
+ - a stable `id` slug (e.g. `spaces.create-post`), unique within its suite;
245
+ - a human-readable `name`;
246
+ - a `run(ctx, state)` function that receives the test context (server URL, test
247
+ actors, and the provisioning/utility helpers) and throws on failure.
248
+
249
+ Register a new suite by adding it to the registry in
250
+ [`src/suites/index.ts`](src/suites/index.ts). Write assertions through the local
251
+ assert module ([`src/harness/assert.ts`](src/harness/assert.ts)) so they work
252
+ unchanged in both Node and the browser.
253
+
254
+ ## Contribute
255
+
256
+ PRs accepted. See [CONTRIBUTING.md](CONTRIBUTING.md) for editor setup (Prettier,
257
+ ESLint, and EditorConfig) and how it maps to CI.
258
+
259
+ If editing the Readme, please conform to the
260
+ [standard-readme](https://github.com/RichardLitt/standard-readme) specification.
261
+
262
+ ## License
263
+
264
+ [MIT License](LICENSE.md) © 2026 Interop Alliance. </content> </invoke>
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
@@ -0,0 +1,69 @@
1
+ #!/usr/bin/env node
2
+ /*!
3
+ * Copyright (c) 2026 Interop Alliance. All rights reserved.
4
+ */
5
+ /**
6
+ * The `was-conformance` bin entry: reads the tool and client versions from the
7
+ * installed packages, binds real process I/O, and delegates to the testable
8
+ * `main()`. All logic lives in `./main.js`.
9
+ */
10
+ import { readFileSync } from 'node:fs';
11
+ import { createRequire } from 'node:module';
12
+ import { dirname, join } from 'node:path';
13
+ import { fileURLToPath } from 'node:url';
14
+ import { runConformance } from '../index.js';
15
+ import { suites } from '../suites/index.js';
16
+ import { main } from './main.js';
17
+ /** Reads this tool's own version from its package.json (../../ from dist/cli). */
18
+ function readToolVersion() {
19
+ try {
20
+ const pkgPath = join(dirname(fileURLToPath(import.meta.url)), '../../package.json');
21
+ return JSON.parse(readFileSync(pkgPath, 'utf8')).version ?? '0.0.0';
22
+ }
23
+ catch {
24
+ return '0.0.0';
25
+ }
26
+ }
27
+ /**
28
+ * Best-effort `@interop/was-client` version: its package.json is not exported,
29
+ * so resolve the entry module and walk up to the owning package manifest.
30
+ */
31
+ function readClientVersion() {
32
+ try {
33
+ const require = createRequire(import.meta.url);
34
+ let dir = dirname(require.resolve('@interop/was-client'));
35
+ for (let i = 0; i < 8; i++) {
36
+ try {
37
+ const pkg = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
38
+ if (pkg.name === '@interop/was-client') {
39
+ return pkg.version;
40
+ }
41
+ }
42
+ catch {
43
+ // Keep walking up to the package root.
44
+ }
45
+ const parent = dirname(dir);
46
+ if (parent === dir) {
47
+ break;
48
+ }
49
+ dir = parent;
50
+ }
51
+ }
52
+ catch {
53
+ // No client version available; the JSON reporter simply omits it.
54
+ }
55
+ return undefined;
56
+ }
57
+ const exitCode = await main(process.argv.slice(2), {
58
+ runConformance,
59
+ suites,
60
+ fetch: globalThis.fetch,
61
+ stdout: text => process.stdout.write(text),
62
+ stderr: text => process.stderr.write(text),
63
+ env: process.env,
64
+ isTTY: Boolean(process.stdout.isTTY),
65
+ version: readToolVersion(),
66
+ clientVersion: readClientVersion()
67
+ });
68
+ process.exitCode = exitCode;
69
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;GAEG;AACH;;;;GAIG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAC5C,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAEhC,kFAAkF;AAClF,SAAS,eAAe;IACtB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAI,CAClB,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EACvC,oBAAoB,CACrB,CAAA;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,OAAO,CAAA;IACrE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAA;IAChB,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,SAAS,iBAAiB;IACxB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QAC9C,IAAI,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,CAAC,CAAC,CAAA;QACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC3B,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC,CAAA;gBACvE,IAAI,GAAG,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;oBACvC,OAAO,GAAG,CAAC,OAAO,CAAA;gBACpB,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,uCAAuC;YACzC,CAAC;YACD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAA;YAC3B,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;gBACnB,MAAK;YACP,CAAC;YACD,GAAG,GAAG,MAAM,CAAA;QACd,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,kEAAkE;IACpE,CAAC;IACD,OAAO,SAAS,CAAA;AAClB,CAAC;AAED,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;IACjD,cAAc;IACd,MAAM;IACN,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;IAC1C,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC;IAC1C,GAAG,EAAE,OAAO,CAAC,GAAG;IAChB,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;IACpC,OAAO,EAAE,eAAe,EAAE;IAC1B,aAAa,EAAE,iBAAiB,EAAE;CACnC,CAAC,CAAA;AAEF,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAA"}
@@ -0,0 +1,64 @@
1
+ import { runConformance } from '../index.js';
2
+ import type { Suite } from '../harness/types.js';
3
+ /** The I/O and collaborators the CLI needs, injectable for tests. */
4
+ export interface CliDeps {
5
+ runConformance: typeof runConformance;
6
+ /** The suite registry to draw from (default: the full registry). */
7
+ suites: Array<Suite<any>>;
8
+ /** Connectivity probe; any resolved response counts as reachable. */
9
+ fetch: typeof fetch;
10
+ stdout: (text: string) => void;
11
+ stderr: (text: string) => void;
12
+ env: Record<string, string | undefined>;
13
+ /** Whether stdout is a TTY, used (with NO_COLOR) to gate ANSI color. */
14
+ isTTY: boolean;
15
+ /** This tool's version, read from its package by the bin wrapper. */
16
+ version: string;
17
+ /** The `@interop/was-client` version, if cheaply resolvable. */
18
+ clientVersion?: string;
19
+ }
20
+ /** A validated run configuration, produced by `parseArgv`. */
21
+ interface RunConfig {
22
+ serverUrl: string;
23
+ onboardingToken: string | null;
24
+ suiteIds: string[];
25
+ grep: string | null;
26
+ includeOptional: boolean;
27
+ skipOptional: boolean;
28
+ reporter: 'pretty' | 'json';
29
+ timeoutMs: number | null;
30
+ failFast: boolean;
31
+ }
32
+ type ParseResult = {
33
+ kind: 'run';
34
+ config: RunConfig;
35
+ } | {
36
+ kind: 'help';
37
+ } | {
38
+ kind: 'version';
39
+ } | {
40
+ kind: 'usage';
41
+ message: string;
42
+ };
43
+ /**
44
+ * Parses argv (the tokens after `node script`) into a `ParseResult`, resolving
45
+ * env fallbacks. Pure: it never touches the network or the suite registry, so
46
+ * arg handling is unit-testable on its own.
47
+ *
48
+ * @param argv {string[]} the raw argument tokens
49
+ * @param env {object} the environment (for TEST_SERVER_URL / token fallbacks)
50
+ * @returns {ParseResult}
51
+ */
52
+ export declare function parseArgv(argv: string[], env: Record<string, string | undefined>): ParseResult;
53
+ /**
54
+ * The CLI entry point, minus process wiring. Returns the intended exit code:
55
+ * 0 = all required tests passed, 1 = conformance failures, 2 = usage error or
56
+ * unreachable server.
57
+ *
58
+ * @param argv {string[]} argument tokens (after `node script`)
59
+ * @param deps {CliDeps} injected I/O and collaborators
60
+ * @returns {Promise<number>} the exit code
61
+ */
62
+ export declare function main(argv: string[], deps: CliDeps): Promise<number>;
63
+ export {};
64
+ //# sourceMappingURL=main.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/cli/main.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAG5C,OAAO,KAAK,EAAuB,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAErE,qEAAqE;AACrE,MAAM,WAAW,OAAO;IACtB,cAAc,EAAE,OAAO,cAAc,CAAA;IACrC,oEAAoE;IACpE,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAA;IACzB,qEAAqE;IACrE,KAAK,EAAE,OAAO,KAAK,CAAA;IACnB,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IAC9B,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IACvC,wEAAwE;IACxE,KAAK,EAAE,OAAO,CAAA;IACd,qEAAqE;IACrE,OAAO,EAAE,MAAM,CAAA;IACf,gEAAgE;IAChE,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,8DAA8D;AAC9D,UAAU,SAAS;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,eAAe,EAAE,MAAM,GAAG,IAAI,CAAA;IAC9B,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IACnB,eAAe,EAAE,OAAO,CAAA;IACxB,YAAY,EAAE,OAAO,CAAA;IACrB,QAAQ,EAAE,QAAQ,GAAG,MAAM,CAAA;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;CAClB;AAED,KAAK,WAAW,GACZ;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,GACnB;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAA;AAoBtC;;;;;;;;GAQG;AACH,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EAAE,EACd,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GACtC,WAAW,CAyGb;AAyFD;;;;;;;;GAQG;AACH,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAyEzE"}