@techspokes/typescript-wsdl-client 0.33.0 → 0.35.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.
- package/README.md +1 -1
- package/dist/test/generators.d.ts.map +1 -1
- package/dist/test/generators.js +19 -12
- package/docs/migration.md +1 -0
- package/docs/releases/v0.34.0.md +30 -0
- package/docs/releases/v0.35.0.md +33 -0
- package/docs/roadmap/README.md +10 -9
- package/docs/roadmap/v1.0-capability-conformance-framework.md +7 -5
- package/docs/roadmap/v1.0-release-candidate-gates.md +9 -3
- package/docs/roadmap/v1.0-wsdl-coverage-matrix.md +21 -13
- package/docs/supported-patterns.md +8 -0
- package/docs/testing.md +29 -0
- package/package.json +8 -8
- package/src/runtime/clientStreamMethods.tpl.txt +1 -1
package/README.md
CHANGED
|
@@ -39,7 +39,7 @@ npm install --save-dev @techspokes/typescript-wsdl-client
|
|
|
39
39
|
npm install soap
|
|
40
40
|
```
|
|
41
41
|
|
|
42
|
-
Requirements: Node.js
|
|
42
|
+
Requirements: Node.js 24+ and the `soap` package as a runtime dependency.
|
|
43
43
|
|
|
44
44
|
## Quick Start
|
|
45
45
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/test/generators.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAA0C,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAG5F,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"generators.d.ts","sourceRoot":"","sources":["../../src/test/generators.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAC,UAAU,EAAE,qBAAqB,EAAC,MAAM,uBAAuB,CAAC;AAC7E,OAAO,EAA0C,KAAK,eAAe,EAAC,MAAM,eAAe,CAAC;AAG5F,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AAsGrF;;;;;GAKG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CAkBzC;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,UAAU,EACtB,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAgFR;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,UAAU,GACrB,MAAM,CAsCR;AAED;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CA8FR;AAED;;;;;;;GAOG;AAEH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAiIR;AAED;;GAEG;AAEH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,EAAE,iBAAiB,GACvB,MAAM,CAuER;AAED;;GAEG;AAEH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,UAAU,EAAE,qBAAqB,EAAE,EACnC,KAAK,CAAC,EAAE,iBAAiB,EACzB,OAAO,CAAC,EAAE,eAAe,GACxB,MAAM,CAwDR;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CACnC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAChC,MAAM,CAgFR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,GAChC,MAAM,CAgDR;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,IAAI,GAAG,IAAI,GAAG,MAAM,EACjC,OAAO,EAAE,eAAe,GACvB,MAAM,GAAG,IAAI,CAkEf"}
|
package/dist/test/generators.js
CHANGED
|
@@ -29,6 +29,13 @@ function isRecord(value) {
|
|
|
29
29
|
function cloneRecord(value) {
|
|
30
30
|
return JSON.parse(JSON.stringify(value));
|
|
31
31
|
}
|
|
32
|
+
function formatInjectPayloadFields(value) {
|
|
33
|
+
if (value == null || typeof value !== "object") {
|
|
34
|
+
return ` headers: {"content-type": "application/json"},
|
|
35
|
+
payload: JSON.stringify(${JSON.stringify(value)}),`;
|
|
36
|
+
}
|
|
37
|
+
return ` payload: ${JSON.stringify(value, null, 4).replace(/\n/g, "\n ")},`;
|
|
38
|
+
}
|
|
32
39
|
function mockChoiceBranchValue(branch, catalog) {
|
|
33
40
|
const isArray = branch.max === "unbounded" || (typeof branch.max === "number" && branch.max > 1);
|
|
34
41
|
const value = branch.tsType === "string" || branch.tsType === "number" || branch.tsType === "boolean"
|
|
@@ -253,7 +260,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
|
|
|
253
260
|
const sortedOps = [...operations].sort((a, b) => a.operationId.localeCompare(b.operationId));
|
|
254
261
|
const testCases = sortedOps.map((op) => {
|
|
255
262
|
const mockData = mocks.get(op.operationId);
|
|
256
|
-
const
|
|
263
|
+
const requestPayloadFields = formatInjectPayloadFields(mockData?.request ?? {});
|
|
257
264
|
const hint = formatOperationHint(op.summary, op.description);
|
|
258
265
|
const hintComment = hint ? ` // ${hint}\n` : "";
|
|
259
266
|
if (op.stream?.format === "json-array") {
|
|
@@ -264,7 +271,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
|
|
|
264
271
|
const res = await app.inject({
|
|
265
272
|
method: "${op.method.toUpperCase()}",
|
|
266
273
|
url: "${op.path}",
|
|
267
|
-
|
|
274
|
+
${requestPayloadFields}
|
|
268
275
|
});
|
|
269
276
|
expect(res.statusCode).toBe(200);
|
|
270
277
|
expect(String(res.headers["content-type"] ?? "")).toContain(${JSON.stringify(op.stream.mediaType)});
|
|
@@ -287,7 +294,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
|
|
|
287
294
|
const res = await app.inject({
|
|
288
295
|
method: "${op.method.toUpperCase()}",
|
|
289
296
|
url: "${op.path}",
|
|
290
|
-
|
|
297
|
+
${requestPayloadFields}
|
|
291
298
|
});
|
|
292
299
|
expect(res.statusCode).toBe(200);
|
|
293
300
|
expect(String(res.headers["content-type"] ?? "")).toContain(${JSON.stringify(op.stream.mediaType)});
|
|
@@ -308,7 +315,7 @@ export function emitRoutesTest(testDir, importsMode, operations, mocks) {
|
|
|
308
315
|
const res = await app.inject({
|
|
309
316
|
method: "${op.method.toUpperCase()}",
|
|
310
317
|
url: "${op.path}",
|
|
311
|
-
|
|
318
|
+
${requestPayloadFields}
|
|
312
319
|
});
|
|
313
320
|
expect(res.statusCode).toBe(200);
|
|
314
321
|
const body = res.json();
|
|
@@ -354,7 +361,7 @@ export function emitErrorsTest(testDir, importsMode, operations, mocks) {
|
|
|
354
361
|
if (!op)
|
|
355
362
|
return "// No operations found\n";
|
|
356
363
|
const mockData = mocks.get(op.operationId);
|
|
357
|
-
const
|
|
364
|
+
const requestPayloadFields = formatInjectPayloadFields(mockData?.request ?? {});
|
|
358
365
|
return `/**
|
|
359
366
|
* Gateway Error Handling Tests
|
|
360
367
|
*
|
|
@@ -379,7 +386,7 @@ describe("gateway routes — error handling", () => {
|
|
|
379
386
|
const res = await app.inject({
|
|
380
387
|
method: "${op.method.toUpperCase()}",
|
|
381
388
|
url: "${op.path}",
|
|
382
|
-
|
|
389
|
+
${requestPayloadFields}
|
|
383
390
|
});
|
|
384
391
|
expect(res.statusCode).toBe(500);
|
|
385
392
|
const body = res.json();
|
|
@@ -413,7 +420,7 @@ describe("gateway routes — error handling", () => {
|
|
|
413
420
|
const res = await app.inject({
|
|
414
421
|
method: "${op.method.toUpperCase()}",
|
|
415
422
|
url: "${op.path}",
|
|
416
|
-
|
|
423
|
+
${requestPayloadFields}
|
|
417
424
|
});
|
|
418
425
|
expect(res.statusCode).toBe(502);
|
|
419
426
|
const body = res.json();
|
|
@@ -436,7 +443,7 @@ describe("gateway routes — error handling", () => {
|
|
|
436
443
|
const res = await app.inject({
|
|
437
444
|
method: "${op.method.toUpperCase()}",
|
|
438
445
|
url: "${op.path}",
|
|
439
|
-
|
|
446
|
+
${requestPayloadFields}
|
|
440
447
|
});
|
|
441
448
|
expect(res.statusCode).toBe(503);
|
|
442
449
|
const body = res.json();
|
|
@@ -459,7 +466,7 @@ describe("gateway routes — error handling", () => {
|
|
|
459
466
|
const res = await app.inject({
|
|
460
467
|
method: "${op.method.toUpperCase()}",
|
|
461
468
|
url: "${op.path}",
|
|
462
|
-
|
|
469
|
+
${requestPayloadFields}
|
|
463
470
|
});
|
|
464
471
|
expect(res.statusCode).toBe(504);
|
|
465
472
|
const body = res.json();
|
|
@@ -486,7 +493,7 @@ export function emitEnvelopeTest(testDir, importsMode, operations, mocks) {
|
|
|
486
493
|
if (!op)
|
|
487
494
|
return "// No operations found\n";
|
|
488
495
|
const mockData = mocks.get(op.operationId);
|
|
489
|
-
const
|
|
496
|
+
const requestPayloadFields = formatInjectPayloadFields(mockData?.request ?? {});
|
|
490
497
|
return `/**
|
|
491
498
|
* Gateway Envelope Structure Tests
|
|
492
499
|
*
|
|
@@ -505,7 +512,7 @@ describe("gateway — envelope structure", () => {
|
|
|
505
512
|
const res = await app.inject({
|
|
506
513
|
method: "${op.method.toUpperCase()}",
|
|
507
514
|
url: "${op.path}",
|
|
508
|
-
|
|
515
|
+
${requestPayloadFields}
|
|
509
516
|
});
|
|
510
517
|
expect(res.statusCode).toBe(200);
|
|
511
518
|
const body = res.json();
|
|
@@ -530,7 +537,7 @@ describe("gateway — envelope structure", () => {
|
|
|
530
537
|
const res = await app.inject({
|
|
531
538
|
method: "${op.method.toUpperCase()}",
|
|
532
539
|
url: "${op.path}",
|
|
533
|
-
|
|
540
|
+
${requestPayloadFields}
|
|
534
541
|
});
|
|
535
542
|
expect(res.statusCode).toBe(500);
|
|
536
543
|
const body = res.json();
|
package/docs/migration.md
CHANGED
|
@@ -18,6 +18,7 @@ These steps apply to every version upgrade:
|
|
|
18
18
|
|
|
19
19
|
| wsdl-tsc | Node.js | TypeScript | soap | Fastify | saxes |
|
|
20
20
|
|----------|---------|------------|------|---------|-------|
|
|
21
|
+
| 0.35.x and later | >= 24.0 | >= 6.0 | >= 1.9 | >= 5.8 | >= 6.0 |
|
|
21
22
|
| 0.17.x | >= 20.0 | >= 6.0 | >= 1.9 | >= 5.8 | >= 6.0 |
|
|
22
23
|
| 0.16.x | >= 20.0 | >= 6.0 | >= 1.9 | >= 5.8 | N/A |
|
|
23
24
|
| 0.15.x | >= 20.0 | >= 6.0 | >= 1.8 | >= 5.4 | N/A |
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# TypeScript WSDL Client v0.34.0
|
|
2
|
+
|
|
3
|
+
## Conformance Gate Readiness
|
|
4
|
+
|
|
5
|
+
This release makes WSDL conformance coverage explicit in the release preflight path without adding a duplicate full test run.
|
|
6
|
+
|
|
7
|
+
## What This Improves
|
|
8
|
+
|
|
9
|
+
Maintainers can now see whether the focused conformance command, broad Vitest discovery, and CI script still line up before a release tag is created. The roadmap also now treats conformance gate wiring as shipped, which moves the 1.0 plan toward resolving remaining explicit deferrals and running release-candidate gates.
|
|
10
|
+
|
|
11
|
+
## Highlights
|
|
12
|
+
|
|
13
|
+
- Adds a release preflight `conformance-gate` check for `test:conformance`, `npm test`, and `npm run ci` wiring.
|
|
14
|
+
- Documents `npm run test:conformance` as the focused command for WSDL capability rows and fixtures.
|
|
15
|
+
- Updates the 1.0 roadmap so validation-gate wiring is no longer an open decision.
|
|
16
|
+
|
|
17
|
+
## Upgrade Notes
|
|
18
|
+
|
|
19
|
+
No special upgrade steps.
|
|
20
|
+
|
|
21
|
+
## Validation
|
|
22
|
+
|
|
23
|
+
- CI passed.
|
|
24
|
+
- NPM package contents were validated.
|
|
25
|
+
- Agent skill artifact was validated and packaged.
|
|
26
|
+
- Release preflight passed against the target tag.
|
|
27
|
+
|
|
28
|
+
## Notes
|
|
29
|
+
|
|
30
|
+
Release tag: `v0.34.0`.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# TypeScript WSDL Client v0.35.0
|
|
2
|
+
|
|
3
|
+
## Baseline Conformance And Node Policy
|
|
4
|
+
|
|
5
|
+
This release expands the WSDL conformance baseline and raises the supported runtime floor to Node 24.
|
|
6
|
+
|
|
7
|
+
## What This Improves
|
|
8
|
+
|
|
9
|
+
Maintainers now have fixture-backed evidence for the common WSDL and XSD patterns that already form the everyday generation baseline: the canonical weather WSDL, complex sequences, simple type restrictions and lists, same-name simple type aliases, simple content with attributes, documentation propagation, SOAP binding detection, and relative XSD imports.
|
|
10
|
+
|
|
11
|
+
The conformance harness also keeps its XML evidence self-contained under `test/conformance/fixtures/`, which makes the public support matrix easier to trust during release review. CI now covers Node 24 as the supported floor and Node 26 as the current line, while release workflows run on Node 24.
|
|
12
|
+
|
|
13
|
+
## Highlights
|
|
14
|
+
|
|
15
|
+
- Adds baseline WSDL and XSD conformance rows across compile, client, OpenAPI, gateway, generated-test, and app stages.
|
|
16
|
+
- Raises the package engine floor to Node 24 and release-gates Node 24 and Node 26 CI coverage.
|
|
17
|
+
- Keeps repository-owned temporary outputs in classified `tmp/` subfolders for smoke, conformance, preflight, npm cache, and generated-test workspaces.
|
|
18
|
+
- Hardens generated gateway tests for scalar JSON payloads.
|
|
19
|
+
|
|
20
|
+
## Upgrade Notes
|
|
21
|
+
|
|
22
|
+
Consumers should run Node 24 or newer.
|
|
23
|
+
|
|
24
|
+
## Validation
|
|
25
|
+
|
|
26
|
+
- CI passed.
|
|
27
|
+
- NPM package contents were validated.
|
|
28
|
+
- Agent skill artifact was validated and packaged.
|
|
29
|
+
- Release preflight passed against the target tag.
|
|
30
|
+
|
|
31
|
+
## Notes
|
|
32
|
+
|
|
33
|
+
Release tag: `v0.35.0`.
|
package/docs/roadmap/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Version 1.0 Roadmap Plan
|
|
2
2
|
|
|
3
|
-
Detailed plan for moving `@techspokes/typescript-wsdl-client` from the
|
|
3
|
+
Detailed plan for moving `@techspokes/typescript-wsdl-client` from the current `0.x` line to a stable `1.0.0` release.
|
|
4
4
|
|
|
5
5
|
See the root [README.md](../../README.md) for project overview and the root [ROADMAP.md](../../ROADMAP.md) for the public roadmap summary.
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ See the root [README.md](../../README.md) for project overview and the root [ROA
|
|
|
8
8
|
|
|
9
9
|
This plan turns the 1.0 roadmap into implementation slices that can be picked up independently. Each slice has its own plan document with scope, testing strategy, acceptance gates, and release implications.
|
|
10
10
|
|
|
11
|
-
The plan is optimized for preserving quality. The contract and compatibility baselines now exist, choice union mode is shipped,
|
|
11
|
+
The plan is optimized for preserving quality. The contract and compatibility baselines now exist, choice union mode is shipped, JSON array streaming is shipped, and the conformance framework is wired into validation gates. The remaining readiness work is to resolve any explicit conformance deferrals and run the final release candidate gate pass.
|
|
12
12
|
|
|
13
13
|
## Route Summary
|
|
14
14
|
|
|
@@ -18,9 +18,9 @@ The plan is optimized for preserving quality. The contract and compatibility bas
|
|
|
18
18
|
| OpenAPI compatibility | [OpenAPI Fastify Compatibility](v1.0-openapi-fastify-compatibility.md) | baseline complete | Schema strategy is proven |
|
|
19
19
|
| Choice union mode | [Choice Union Mode](v1.0-choice-union-mode.md) | complete | Implemented in `0.26.0` |
|
|
20
20
|
| JSON array streaming | [JSON Array Streaming](v1.0-json-array-streaming.md) | complete | Implemented in `0.28.0` |
|
|
21
|
-
| Conformance framework | [Capability Conformance Framework](v1.0-capability-conformance-framework.md) |
|
|
22
|
-
| WSDL coverage matrix | [WSDL Coverage Matrix](v1.0-wsdl-coverage-matrix.md) |
|
|
23
|
-
| Release candidate | [Release Candidate Gates](v1.0-release-candidate-gates.md) |
|
|
21
|
+
| Conformance framework | [Capability Conformance Framework](v1.0-capability-conformance-framework.md) | gate wired | Pipeline claims are test-backed |
|
|
22
|
+
| WSDL coverage matrix | [WSDL Coverage Matrix](v1.0-wsdl-coverage-matrix.md) | baseline registry | Public support is test-backed |
|
|
23
|
+
| Release candidate | [Release Candidate Gates](v1.0-release-candidate-gates.md) | next | 1.0 release is repeatable |
|
|
24
24
|
|
|
25
25
|
## Execution Order
|
|
26
26
|
|
|
@@ -42,11 +42,11 @@ JSON array streaming is complete in `0.28.0`. The default `ndjson` format remain
|
|
|
42
42
|
|
|
43
43
|
### Slice 5: Capability Conformance Framework
|
|
44
44
|
|
|
45
|
-
The registry, fixture strategy, compile runner, client evidence, OpenAPI evidence, gateway runtime evidence, generated-test evidence, app evidence, documentation drift check,
|
|
45
|
+
The registry, fixture strategy, compile runner, client evidence, OpenAPI evidence, gateway runtime evidence, generated-test evidence, app evidence, documentation drift check, generated support matrix, and validation-gate wiring are shipped. The registry is the public baseline support source, while examples remain demos. Keep `npm run test:conformance` as the focused local command while broad Vitest discovery covers conformance in `npm test`, `npm run ci`, and release preflight.
|
|
46
46
|
|
|
47
47
|
### Slice 6: WSDL Coverage Matrix
|
|
48
48
|
|
|
49
|
-
The
|
|
49
|
+
The WSDL matrix rows now exist as conformance registry entries with compile, client, OpenAPI, gateway runtime, generated-test, app, documentation, and release-gate evidence. The next work is to keep those rows current while release candidate gates are prepared.
|
|
50
50
|
|
|
51
51
|
### Slice 7: Release Candidate Gates
|
|
52
52
|
|
|
@@ -54,7 +54,6 @@ Run the release candidate gates after feature work and documentation have conver
|
|
|
54
54
|
|
|
55
55
|
## Remaining Before 1.0
|
|
56
56
|
|
|
57
|
-
- Decide which conformance checks should run in CI, release preflight, or local-only workflows.
|
|
58
57
|
- Turn remaining unsupported, diagnostic, or partial matrix rows into diagnostics, documentation, or scoped fixes.
|
|
59
58
|
- Confirm `docs/supported-patterns.md` matches the matrix.
|
|
60
59
|
- Run the release-candidate gates.
|
|
@@ -84,7 +83,9 @@ Run the release candidate gates after feature work and documentation have conver
|
|
|
84
83
|
|
|
85
84
|
### Coverage Gate
|
|
86
85
|
|
|
87
|
-
- A capability conformance matrix runs under test automation.
|
|
86
|
+
- A capability conformance matrix runs under broad Vitest test automation.
|
|
87
|
+
- Release preflight verifies the focused conformance command and CI wiring.
|
|
88
|
+
- Release preflight verifies CI covers Node 24 and Node 26 and release workflows use Node 24.
|
|
88
89
|
- Each matrix entry has a fixture, status, and stage expectations.
|
|
89
90
|
- Unsupported features fail loudly or are documented as deliberately unsupported.
|
|
90
91
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Version 1.0 Capability Conformance Framework
|
|
2
2
|
|
|
3
|
-
Status: Phase
|
|
3
|
+
Status: Phase 5 shipped; release-candidate gate pass remaining before `1.0.0`.
|
|
4
4
|
|
|
5
5
|
Plan for turning SOAP, WSDL, OpenAPI, gateway, app, generated-test, and documentation support claims into fixture-backed conformance evidence.
|
|
6
6
|
|
|
7
|
-
Phase 1 shipped a TypeScript registry, reusable WSDL fixtures, compile-stage runner, documentation drift tests, and generated public support matrix. Phase 2 added generated client type-checking, OpenAPI validation, and executable diagnostics for terminal rows. Phase 3 added generated gateway type-checking and Fastify runtime evidence for current supported and partial rows. Phase 4 added generated-test and app scaffold evidence for those rows.
|
|
7
|
+
Phase 1 shipped a TypeScript registry, reusable WSDL fixtures, compile-stage runner, documentation drift tests, and generated public support matrix. Phase 2 added generated client type-checking, OpenAPI validation, and executable diagnostics for terminal rows. Phase 3 added generated gateway type-checking and Fastify runtime evidence for current supported and partial rows. Phase 4 added generated-test and app scaffold evidence for those rows. Phase 5 wired conformance into validation gates through broad Vitest discovery and release preflight script verification.
|
|
8
8
|
|
|
9
9
|
See the root [README.md](../../README.md) for project overview and [Version 1.0 Roadmap Plan](README.md) for the complete 1.0 route.
|
|
10
10
|
|
|
@@ -545,12 +545,15 @@ Acceptance criteria:
|
|
|
545
545
|
|
|
546
546
|
## Phase 5: Documentation And Release Gates
|
|
547
547
|
|
|
548
|
-
|
|
548
|
+
Phase 5 is implemented. Keep this section as the baseline for conformance gate ownership.
|
|
549
|
+
|
|
550
|
+
`npm run test:conformance` remains the focused maintainer command for WSDL capability rows. `npm test` and `npm run ci` cover conformance through broad Vitest discovery, so release preflight does not run a duplicate full conformance pass. Release preflight instead runs a cheap `conformance-gate` script check that fails if the focused command disappears, if `npm test` becomes scoped away from `test/conformance`, or if `npm run ci` stops running the broad test command.
|
|
549
551
|
|
|
550
552
|
Acceptance criteria:
|
|
551
553
|
|
|
552
554
|
- `docs/supported-patterns.md` cannot drift from the registry.
|
|
553
|
-
- CI
|
|
555
|
+
- CI runs conformance through broad Vitest discovery.
|
|
556
|
+
- Release preflight verifies conformance command and CI wiring.
|
|
554
557
|
- Full conformance can run locally before `1.0.0`.
|
|
555
558
|
- Release notes can cite capability IDs for behavior changes.
|
|
556
559
|
|
|
@@ -567,7 +570,6 @@ Acceptance criteria:
|
|
|
567
570
|
|
|
568
571
|
## Open Decisions
|
|
569
572
|
|
|
570
|
-
- Decide how much generated output type-checking is acceptable in CI runtime.
|
|
571
573
|
- Decide which inspector output format becomes public before `1.0.0`.
|
|
572
574
|
- Decide whether docs should remain manually maintained or eventually generated from the registry.
|
|
573
575
|
|
|
@@ -33,7 +33,11 @@ Run `npm run docs:validate`. Confirm README, CLI reference, API reference, confi
|
|
|
33
33
|
|
|
34
34
|
### Test Gate
|
|
35
35
|
|
|
36
|
-
Run `npm test`. Confirm unit, snapshot, and
|
|
36
|
+
Run `npm test`. Confirm unit, snapshot, integration, and conformance suites cover the 1.0 contract.
|
|
37
|
+
|
|
38
|
+
### Conformance Gate
|
|
39
|
+
|
|
40
|
+
Run `npm run test:conformance` when changing capability rows or fixture-backed behavior. Confirm `npm test` and `npm run ci` keep broad Vitest discovery so `test/conformance` stays covered, and confirm release preflight reports a passing `conformance-gate` script check.
|
|
37
41
|
|
|
38
42
|
### Smoke Gate
|
|
39
43
|
|
|
@@ -49,11 +53,11 @@ Run the generated example freshness check through release preflight. Confirm com
|
|
|
49
53
|
|
|
50
54
|
### Node Gate
|
|
51
55
|
|
|
52
|
-
Run the supported Node.js floor and
|
|
56
|
+
Run Node 24 as the supported Node.js floor and Node 26 as the current line in CI before the release candidate is accepted. Release workflows should run on Node 24, and release preflight should fail if CI stops covering either line.
|
|
53
57
|
|
|
54
58
|
### Release Gate
|
|
55
59
|
|
|
56
|
-
Run `npm run release:preflight -- v1.0.0` during release preparation. Confirm release notes, changelog, dependency pins, generated examples, CI, and skill packaging pass.
|
|
60
|
+
Run `npm run release:preflight -- v1.0.0` during release preparation. Confirm release notes, changelog, dependency pins, conformance wiring, generated examples, CI, and skill packaging pass.
|
|
57
61
|
|
|
58
62
|
## Documentation Checklist
|
|
59
63
|
|
|
@@ -62,6 +66,8 @@ Run `npm run release:preflight -- v1.0.0` during release preparation. Confirm re
|
|
|
62
66
|
- API reference lists implemented options only.
|
|
63
67
|
- Configuration docs describe both stream formats.
|
|
64
68
|
- Supported patterns reflects the WSDL matrix.
|
|
69
|
+
- The conformance gate documents `npm run test:conformance`, broad Vitest discovery, and release preflight wiring.
|
|
70
|
+
- The Node gate documents Node 24 as the package floor and Node 26 as the current-line CI check.
|
|
65
71
|
- Production docs describe terminal-error behavior for both stream formats.
|
|
66
72
|
- Migration docs explain any behavior changes since `0.x`.
|
|
67
73
|
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# Version 1.0 WSDL Coverage Matrix
|
|
2
2
|
|
|
3
|
-
Status: generated-test
|
|
3
|
+
Status: baseline support registry, generated-test evidence, app evidence, and validation-gate wiring shipped before `1.0.0`.
|
|
4
4
|
|
|
5
5
|
Plan for turning WSDL and XSD support claims into automated, fixture-backed evidence before 1.0. This is the first domain under the [Capability Conformance Framework](v1.0-capability-conformance-framework.md).
|
|
6
6
|
|
|
7
|
-
The initial fixture-backed compile matrix shipped in `0.30.2` and `0.30.3`. Client, OpenAPI, gateway runtime, generated-test, and app evidence now prove the current supported and partial rows, and terminal rows have executable diagnostics. The
|
|
7
|
+
The initial fixture-backed compile matrix shipped in `0.30.2` and `0.30.3`. Client, OpenAPI, gateway runtime, generated-test, and app evidence now prove the current supported and partial rows, and terminal rows have executable diagnostics. The matrix is now the public baseline support registry. Examples remain demos, while conformance fixtures are the durable support evidence. `npm test` and `npm run ci` cover the conformance suite through broad Vitest discovery, and release preflight verifies that the script wiring remains intact.
|
|
8
8
|
|
|
9
9
|
See the root [README.md](../../README.md) for project overview and [Version 1.0 Roadmap Plan](README.md) for the complete 1.0 route.
|
|
10
10
|
|
|
11
11
|
## Goal
|
|
12
12
|
|
|
13
|
-
The project should have an automated WSDL and XSD feature matrix that proves which patterns are supported, partially supported, or rejected with diagnostics. The matrix
|
|
13
|
+
The project should have an automated WSDL and XSD feature matrix that proves which patterns are supported, partially supported, or rejected with diagnostics. The matrix is the conformance registry, aligns with `docs/supported-patterns.md`, and protects 1.0 from silent miscompilation.
|
|
14
14
|
|
|
15
15
|
## Design Direction
|
|
16
16
|
|
|
17
|
-
Each matrix row should have a minimal fixture, an expected support status, and a test that proves the status. A supported feature must compile and generate aligned client, OpenAPI, and
|
|
17
|
+
Each matrix row should have a minimal fixture, an expected support status, and a test that proves the status. A supported or partial feature must compile and generate aligned client, OpenAPI, gateway, generated-test, and app artifacts unless the row documents why a stage is inapplicable. An unsupported, diagnostic, or terminal feature must stop before downstream generation and fail with a clear diagnostic or be documented as intentionally out of scope.
|
|
18
18
|
|
|
19
19
|
## Shipped Baseline
|
|
20
20
|
|
|
21
|
-
- `test/conformance/fixtures/` contains the
|
|
22
|
-
- `test/conformance/registry.ts` lists
|
|
21
|
+
- `test/conformance/fixtures/` contains the baseline WSDL and XSD support fixture set.
|
|
22
|
+
- `test/conformance/registry.ts` lists baseline support rows with status, decision, provenance, and public contract text.
|
|
23
23
|
- `test/conformance/conformance.test.ts` runs compile-stage expectations for runnable rows.
|
|
24
24
|
- Supported and partial rows generate client artifacts that type-check.
|
|
25
25
|
- Supported and partial rows generate validated OpenAPI specs with targeted contract assertions.
|
|
@@ -30,10 +30,9 @@ Each matrix row should have a minimal fixture, an expected support status, and a
|
|
|
30
30
|
|
|
31
31
|
## Remaining Scope
|
|
32
32
|
|
|
33
|
-
- Decide which conformance checks should run in CI, release preflight, and focused local commands.
|
|
34
33
|
- Keep diagnostics executable as more unsupported rows are added.
|
|
35
34
|
- Keep fixture metadata useful for a future public conformance fixture corpus.
|
|
36
|
-
- Preserve the weather smoke fixture as the canonical end-to-end
|
|
35
|
+
- Preserve the weather smoke fixture as the canonical end-to-end demo while the copied conformance fixture proves the baseline support claim.
|
|
37
36
|
|
|
38
37
|
## Out Of Scope
|
|
39
38
|
|
|
@@ -46,6 +45,13 @@ Each matrix row should have a minimal fixture, an expected support status, and a
|
|
|
46
45
|
|
|
47
46
|
| Feature | Expected 1.0 Status | Notes |
|
|
48
47
|
|----------------------------|-------------------------|---------------------------------------|
|
|
48
|
+
| Weather document-literal baseline | supported | Canonical demo also lives in conformance |
|
|
49
|
+
| Complex sequences | supported | Nested references, repeated fields, and optional wrappers |
|
|
50
|
+
| Simple restrictions | supported | Enumerations, list aliases, and same-name aliases |
|
|
51
|
+
| Simple content attributes | supported | `$value` text content and flattened attributes |
|
|
52
|
+
| Documentation propagation | supported | Catalog, TypeScript, OpenAPI, and gateway comments |
|
|
53
|
+
| SOAP binding detection | supported | SOAP 1.1, SOAP 1.2, and first SOAP binding behavior |
|
|
54
|
+
| Relative XSD imports | supported | Local imports with committed companion XSDs |
|
|
49
55
|
| `xs:choice` union mode | supported | Implemented in `0.26.0` |
|
|
50
56
|
| `xs:union` | supported | Simple unions implemented after fixture work |
|
|
51
57
|
| Abstract types | diagnostic | Avoid silent concrete treatment |
|
|
@@ -98,8 +104,8 @@ Ensure every documented unsupported or partial feature has a corresponding matri
|
|
|
98
104
|
## Acceptance Criteria
|
|
99
105
|
|
|
100
106
|
- The matrix includes every roadmap priority feature.
|
|
101
|
-
- Supported rows have compile, client, and
|
|
102
|
-
- Unsupported or
|
|
107
|
+
- Supported and partial rows have compile, client, OpenAPI, gateway, generated-test, and app evidence when those stages apply.
|
|
108
|
+
- Unsupported, diagnostic, or terminal rows fail with clear diagnostics, or are explicitly deferred without support claims.
|
|
103
109
|
- `docs/supported-patterns.md` reflects the matrix.
|
|
104
110
|
- No known feature silently miscompiles in matrix coverage.
|
|
105
111
|
- The matrix can run in CI or release preflight without network access.
|
|
@@ -153,12 +159,14 @@ Partial rows must prove only the documented subset. `xs:anyAttribute` should not
|
|
|
153
159
|
|
|
154
160
|
### Next Slice
|
|
155
161
|
|
|
156
|
-
The next slice is
|
|
162
|
+
The next slice is release-candidate preparation. Run it before adding more feature rows unless a production bug requires a focused diagnostic or support decision.
|
|
157
163
|
|
|
158
164
|
Work items:
|
|
159
165
|
|
|
160
|
-
-
|
|
161
|
-
- Keep
|
|
166
|
+
- Keep `npm run test:conformance` as the focused command for maintainers who want only conformance checks.
|
|
167
|
+
- Keep `npm test` and `npm run ci` broad enough for Vitest to discover `test/conformance`.
|
|
168
|
+
- Keep release preflight's `conformance-gate` script check aligned with the package scripts.
|
|
169
|
+
- Keep release preflight's Node gate aligned with the package engine, Node 24 CI coverage, Node 26 CI coverage, and Node 24 release workflows.
|
|
162
170
|
- Confirm release preflight runtime remains acceptable.
|
|
163
171
|
- Keep diagnostic and unsupported rows stopped at compile.
|
|
164
172
|
- Update public docs only when a row status or public contract changes.
|
|
@@ -9,6 +9,14 @@ The rows below are backed by committed conformance fixtures under `test/conforma
|
|
|
9
9
|
<!-- support-matrix:start -->
|
|
10
10
|
| Capability ID | Status | Public contract |
|
|
11
11
|
|---|---|---|
|
|
12
|
+
| `weather-document-literal-soap` | supported | The canonical weather WSDL compiles through client, OpenAPI, gateway, generated-test, and app artifacts with document-literal SOAP operations. |
|
|
13
|
+
| `sequence-baseline-complex` | supported | Complex type sequences support nested complex references, repeated elements, optional fields, and all-optional request wrappers. |
|
|
14
|
+
| `simple-restriction-list` | supported | Named simple type restrictions, enumerations, and `xs:list` declarations emit aligned TypeScript aliases and OpenAPI schemas. |
|
|
15
|
+
| `same-name-simple-alias` | supported | A global element with the same local name as its named simple type reuses the scalar alias instead of emitting a duplicate wrapper interface. |
|
|
16
|
+
| `simple-content-attributes` | supported | Simple content emits text content through `$value` and flattens XML attributes as peer properties. |
|
|
17
|
+
| `documentation-propagation` | supported | WSDL and XSD documentation propagates into catalog metadata, generated TypeScript comments, OpenAPI descriptions, and gateway route comments. |
|
|
18
|
+
| `soap12-first-binding` | supported | SOAP 1.1 and SOAP 1.2 bindings are detected, and the first SOAP binding deterministically provides operation binding metadata. |
|
|
19
|
+
| `xsd-import-relative` | supported | Relative XSD imports are resolved and imported complex types participate in client, OpenAPI, gateway, generated-test, and app artifacts. |
|
|
12
20
|
| `choice-union-simple` | supported | `xs:choice` union mode retains choice metadata and drives generated TypeScript/OpenAPI constraints. |
|
|
13
21
|
| `xs-union-simple-type` | supported | Simple `xs:union` aliases compile to TypeScript unions and OpenAPI `oneOf` schemas. |
|
|
14
22
|
| `abstract-complex-type` | diagnostic | Abstract complex types are rejected with a diagnostic instead of being treated as concrete. |
|
package/docs/testing.md
CHANGED
|
@@ -21,6 +21,7 @@ npm test # All Vitest tests
|
|
|
21
21
|
npm run test:unit # Unit tests only
|
|
22
22
|
npm run test:snap # Snapshot tests only
|
|
23
23
|
npm run test:integration # Integration tests only
|
|
24
|
+
npm run test:conformance # WSDL capability conformance tests only
|
|
24
25
|
npm run test:watch # Watch mode for development
|
|
25
26
|
```
|
|
26
27
|
|
|
@@ -30,6 +31,22 @@ For the full CI pipeline including smoke tests:
|
|
|
30
31
|
npm run ci
|
|
31
32
|
```
|
|
32
33
|
|
|
34
|
+
## Node Support Policy
|
|
35
|
+
|
|
36
|
+
The package supports Node.js >= 24.0.0. CI runs the complete project check on Node 24 and Node 26 so the supported floor and current Node line are both covered.
|
|
37
|
+
|
|
38
|
+
## Temporary Workspaces
|
|
39
|
+
|
|
40
|
+
Repository test and release automation keeps disposable output classified under `tmp/`:
|
|
41
|
+
|
|
42
|
+
- `tmp/smoke/`: smoke-script client, OpenAPI, gateway, app, and catalog output
|
|
43
|
+
- `tmp/cache/npm/`: local npm cache used by package and dependency checks
|
|
44
|
+
- `tmp/preflight/examples/`: regenerated examples used by release preflight
|
|
45
|
+
- `tmp/conformance/`: conformance mini-projects that need repository-local module resolution
|
|
46
|
+
- `tmp/test-generation/`: generated-test integration spikes
|
|
47
|
+
|
|
48
|
+
Keep new repository-owned temporary writers under the closest existing subfolder. Public CLI examples may still use simple `tmp/...` paths when those examples are clearer for users.
|
|
49
|
+
|
|
33
50
|
## Unit Tests
|
|
34
51
|
|
|
35
52
|
Unit tests cover pure functions with no I/O or side effects:
|
|
@@ -169,6 +186,18 @@ import { pathToFileURL } from "node:url";
|
|
|
169
186
|
const pluginModule = await import(pathToFileURL(join(outDir, "gateway", "plugin.ts")).href);
|
|
170
187
|
```
|
|
171
188
|
|
|
189
|
+
## Conformance Tests
|
|
190
|
+
|
|
191
|
+
Conformance tests live under `test/conformance/` and prove WSDL capability claims through committed fixtures, registry rows, generated artifacts, diagnostics, and documentation alignment. Use the focused command when changing capability rows or fixture-backed behavior:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
npm run test:conformance
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
`npm test` includes the conformance suite through normal Vitest discovery. `npm run ci` and release preflight cover conformance through that broad test command, while release preflight also checks that the focused command and broad CI discovery remain wired.
|
|
198
|
+
|
|
199
|
+
Examples under `examples/` are consumer-facing demos and smoke-test inputs. Reusable WSDL and XSD behavior that represents a public support claim belongs in `test/conformance/fixtures/` with a matching registry row.
|
|
200
|
+
|
|
172
201
|
## Known Issues
|
|
173
202
|
|
|
174
203
|
### ArrayOf* Schema-Type Mismatch (Resolved)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techspokes/typescript-wsdl-client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.35.0",
|
|
4
4
|
"description": "Turn legacy WSDL/SOAP services into typed TypeScript clients, OpenAPI 3.1 specs, and production-ready Fastify REST gateways. Built for enterprise SOAP modernization.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"wsdl",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
],
|
|
36
36
|
"type": "module",
|
|
37
37
|
"engines": {
|
|
38
|
-
"node": ">=
|
|
38
|
+
"node": ">=24.0.0"
|
|
39
39
|
},
|
|
40
40
|
"bin": {
|
|
41
41
|
"wsdl-tsc": "dist/cli.js"
|
|
@@ -74,12 +74,12 @@
|
|
|
74
74
|
"test:watch": "vitest",
|
|
75
75
|
"prepublishOnly": "npm run clean && npm run build && npm run package:validate",
|
|
76
76
|
"smoke:reset": "npm run clean:tmp",
|
|
77
|
-
"smoke:compile": "npm run smoke:reset && tsx src/cli.ts compile --wsdl-source examples/minimal/weather.wsdl --catalog-file tmp/catalog.json",
|
|
78
|
-
"smoke:client": "npm run smoke:reset && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client && tsc -p tsconfig.smoke.json",
|
|
79
|
-
"smoke:openapi": "npm run smoke:reset && tsx src/cli.ts openapi --wsdl-source examples/minimal/weather.wsdl --openapi-file tmp/openapi.json --openapi-format json && tsc -p tsconfig.smoke.json",
|
|
80
|
-
"smoke:gateway": "npm run smoke:reset && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client && tsx src/cli.ts openapi --catalog-file tmp/client/catalog.json --openapi-file tmp/openapi.json --openapi-format json && tsx src/cli.ts gateway --openapi-file tmp/openapi.json --client-dir tmp/client --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 && tsc -p tsconfig.smoke.json",
|
|
81
|
-
"smoke:pipeline": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --init-app && tsc -p tsconfig.smoke.json",
|
|
82
|
-
"smoke:app": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/client --openapi-file tmp/openapi.json --gateway-dir tmp/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api && tsx src/cli.ts app --client-dir tmp/client --gateway-dir tmp/gateway --openapi-file tmp/openapi.json --app-dir tmp/app --port 8080 && tsc -p tsconfig.smoke.json",
|
|
77
|
+
"smoke:compile": "npm run smoke:reset && tsx src/cli.ts compile --wsdl-source examples/minimal/weather.wsdl --catalog-file tmp/smoke/catalog.json",
|
|
78
|
+
"smoke:client": "npm run smoke:reset && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/smoke/client && tsc -p tsconfig.smoke.json",
|
|
79
|
+
"smoke:openapi": "npm run smoke:reset && tsx src/cli.ts openapi --wsdl-source examples/minimal/weather.wsdl --openapi-file tmp/smoke/openapi.json --openapi-format json && tsc -p tsconfig.smoke.json",
|
|
80
|
+
"smoke:gateway": "npm run smoke:reset && tsx src/cli.ts client --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/smoke/client && tsx src/cli.ts openapi --catalog-file tmp/smoke/client/catalog.json --openapi-file tmp/smoke/openapi.json --openapi-format json && tsx src/cli.ts gateway --openapi-file tmp/smoke/openapi.json --client-dir tmp/smoke/client --gateway-dir tmp/smoke/gateway --gateway-service-name weather --gateway-version-prefix v1 && tsc -p tsconfig.smoke.json",
|
|
81
|
+
"smoke:pipeline": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/smoke/client --openapi-file tmp/smoke/openapi.json --gateway-dir tmp/smoke/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --init-app && tsc -p tsconfig.smoke.json",
|
|
82
|
+
"smoke:app": "npm run smoke:reset && tsx src/cli.ts pipeline --wsdl-source examples/minimal/weather.wsdl --client-dir tmp/smoke/client --openapi-file tmp/smoke/openapi.json --gateway-dir tmp/smoke/gateway --gateway-service-name weather --gateway-version-prefix v1 --openapi-format json --openapi-servers https://example.com/api && tsx src/cli.ts app --client-dir tmp/smoke/client --gateway-dir tmp/smoke/gateway --openapi-file tmp/smoke/openapi.json --app-dir tmp/smoke/app --port 8080 && tsc -p tsconfig.smoke.json",
|
|
83
83
|
"maint:deps": "node scripts/maint-deps.mjs",
|
|
84
84
|
"docs:support-matrix": "tsx scripts/generate-support-matrix.ts",
|
|
85
85
|
"docs:support-matrix:check": "tsx scripts/generate-support-matrix.ts --check",
|
|
@@ -163,7 +163,7 @@
|
|
|
163
163
|
}
|
|
164
164
|
|
|
165
165
|
/**
|
|
166
|
-
* Iterate an uploaded web ReadableStream as Uint8Array chunks. Node
|
|
166
|
+
* Iterate an uploaded web ReadableStream as Uint8Array chunks. Node 24+
|
|
167
167
|
* ReadableStream implements Symbol.asyncIterator natively; this helper
|
|
168
168
|
* normalizes the types so TypeScript can drive it through \`for await\`.
|
|
169
169
|
*/
|