@mcp-abap-adt/adt-clients 37.0.0 → 37.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/README.md +56 -4
  2. package/dist/core/class/index.d.ts +1 -1
  3. package/dist/core/class/index.d.ts.map +1 -1
  4. package/dist/core/class/index.js +2 -1
  5. package/dist/core/class/run.d.ts +11 -0
  6. package/dist/core/class/run.d.ts.map +1 -1
  7. package/dist/core/class/run.js +18 -0
  8. package/dist/core/shared/abapUnit.d.ts +46 -0
  9. package/dist/core/shared/abapUnit.d.ts.map +1 -1
  10. package/dist/core/shared/abapUnit.js +98 -0
  11. package/dist/executors/abapUnitRunner.d.ts +9 -0
  12. package/dist/executors/abapUnitRunner.d.ts.map +1 -1
  13. package/dist/executors/abapUnitRunner.js +14 -0
  14. package/dist/executors/class/ClassTestRunner.d.ts +27 -1
  15. package/dist/executors/class/ClassTestRunner.d.ts.map +1 -1
  16. package/dist/executors/class/ClassTestRunner.js +31 -0
  17. package/dist/executors/class/ClassTestRunnerLegacy.d.ts +6 -0
  18. package/dist/executors/class/ClassTestRunnerLegacy.d.ts.map +1 -1
  19. package/dist/executors/class/ClassTestRunnerLegacy.js +12 -5
  20. package/dist/executors/functionGroup/FunctionGroupTestRunner.d.ts +25 -1
  21. package/dist/executors/functionGroup/FunctionGroupTestRunner.d.ts.map +1 -1
  22. package/dist/executors/functionGroup/FunctionGroupTestRunner.js +30 -1
  23. package/dist/executors/functionModule/FunctionModuleTestRunner.d.ts +47 -2
  24. package/dist/executors/functionModule/FunctionModuleTestRunner.d.ts.map +1 -1
  25. package/dist/executors/functionModule/FunctionModuleTestRunner.js +48 -1
  26. package/dist/executors/functionModule/index.d.ts +1 -1
  27. package/dist/executors/functionModule/index.d.ts.map +1 -1
  28. package/dist/executors/index.d.ts +1 -1
  29. package/dist/executors/index.d.ts.map +1 -1
  30. package/dist/executors/program/ProgramTestRunner.d.ts +30 -3
  31. package/dist/executors/program/ProgramTestRunner.d.ts.map +1 -1
  32. package/dist/executors/program/ProgramTestRunner.js +33 -3
  33. package/dist/executors/program/ProgramTestRunnerLegacy.d.ts +7 -4
  34. package/dist/executors/program/ProgramTestRunnerLegacy.d.ts.map +1 -1
  35. package/dist/executors/program/ProgramTestRunnerLegacy.js +9 -4
  36. package/dist/index.executors.d.ts +1 -1
  37. package/dist/index.executors.d.ts.map +1 -1
  38. package/docs/usage/OBJECT_LIFECYCLE.md +2 -2
  39. package/package.json +25 -18
  40. package/dist/core/class/runLegacy.d.ts +0 -42
  41. package/dist/core/class/runLegacy.d.ts.map +0 -1
  42. package/dist/core/class/runLegacy.js +0 -74
package/README.md CHANGED
@@ -157,9 +157,9 @@ npm install @mcp-abap-adt/adt-clients
157
157
  - Typed execution API based on `IExecutor`
158
158
  - Executors:
159
159
  - `getClassExecutor()` for `classrun`
160
- - `getClassTestRunner()` for a class's ABAP Unit tests: `run`, `getStatus`, `getResult`
161
- - `getProgramTestRunner()` for a report's ABAP Unit tests, in its source or its includes
162
- - `getFunctionGroupTestRunner()` / `getFunctionModuleTestRunner()` for a function group's tests, or the ones exercising one module
160
+ - `getClassTestRunner()` for a class's ABAP Unit tests: `run`, `getStatus`, `getResult` (asynchronous, the default), or `runSync` (synchronous)
161
+ - `getProgramTestRunner()` for a report's ABAP Unit tests, in its source or its includes — `run` (asynchronous, the default) or `runSync`
162
+ - `getFunctionGroupTestRunner()` / `getFunctionModuleTestRunner()` for a function group's tests, or a module's — `run` (asynchronous, the default) or `runSync`
163
163
  - `getProgramExecutor()` for `programrun` (on-premise systems)
164
164
  - Methods: `run`, `runWithProfiler`, and trace scheduling (`scheduleTrace`, `listRequests`, `getRequestsByUri`, `listObjectTypes`, `listProcessTypes`)
165
165
  - Each executor factory takes an optional result set, like the runtime client's
@@ -440,13 +440,65 @@ const result = await runner.getResult(runId, { analyse: analyseUnitTest });
440
440
  `{ containerClass, testClass }`. On a legacy system the runner's `run` answers
441
441
  the finished result, and `getStatus`/`getResult` refuse without a request.
442
442
 
443
+ **The synchronous runner, `runSync`.** `run` starts a run on
444
+ `/sap/bc/adt/abapunit/runs`, which is then polled; that stays the default.
445
+ `runSync` is the other runner ADT has — one `POST /sap/bc/adt/abapunit/testruns`
446
+ answering the finished `aunit:runResult` — chosen explicitly by the caller.
447
+ Some systems have only this one (an on-prem S/4HANA 2023, SAP_BASIS 758, was
448
+ measured without `/abapunit/runs`); whether a system has `/runs` is in its
449
+ discovery, and reading that is the caller's — the library picks no runner by
450
+ release or by discovery.
451
+
452
+ ```typescript
453
+ const result = await runner.runSync('ZCL_UNDER_TEST', { analyse: analyseUnitTest });
454
+ ```
455
+
456
+ Its answer is read by the runner's `result` strategy, the one `getResult` uses:
457
+ on the measured systems (on premise and ABAP Cloud, 2026-10-22) both runners
458
+ answer the same document — `aunit:runResult` in `http://www.sap.com/adt/aunit`
459
+ — with the same methods and alerts. Two differences: the endpoint addresses
460
+ whole classes, so `{ containerClass, testClass }` targets run each distinct
461
+ container whole; and `title` and `context` are not sent. Scope, risk levels and
462
+ durations are, with `run`'s defaults. On a legacy system `runSync` is the
463
+ request `run` already sends there, read by `result`.
464
+
443
465
  A report's tests are local classes in its source or in an include it pulls in —
444
466
  written through `getProgram().update()` or `getInclude().update()` — and run
445
467
  through `executor.getProgramTestRunner().run(programName)`, with the same
446
468
  `getStatus`/`getResult`. A function group's are written in an include of the
447
469
  group (`getFunctionInclude()`) and run through `getFunctionGroupTestRunner()`
448
470
  for the whole group or `getFunctionModuleTestRunner()` for one module. Below
449
- 7.50 these three runners refuse without a request.
471
+ 7.50 these three runners refuse without a request, `runSync` included.
472
+
473
+ All three have `runSync` as well — the same `/abapunit/testruns` request as a
474
+ class's, naming the object by its URI, read by `result` and judged by
475
+ `options.analyse`:
476
+
477
+ ```typescript
478
+ await executor.getProgramTestRunner().runSync('ZREPORT', { analyse: analyseUnitTest });
479
+ await executor.getFunctionGroupTestRunner().runSync('ZGROUP', { analyse: analyseUnitTest });
480
+ await executor
481
+ .getFunctionModuleTestRunner()
482
+ .runSync({ functionGroupName: 'ZGROUP', functionModuleName: 'Z_MODULE' }, { analyse: analyseUnitTest });
483
+ ```
484
+
485
+ Their run configuration always carries `<options>` (scope, risk levels and
486
+ durations, with `run`'s defaults). Measured on premise (SAP_BASIS 816,
487
+ 2026-10-23): with it, a report (test class in its own source or in an include),
488
+ a function group and a function module each ran the same tests with the same
489
+ alerts as `run`; without it the endpoint answered `200` with an empty
490
+ `aunit:runResult`. Name the report, not the include: an include's own URI ran
491
+ nothing, its tests run through the report.
492
+
493
+ **A module's `runSync` runs its whole group's tests.** The module's URI lies
494
+ under its group's, so the target names both. On the measured system it ran
495
+ every test of the group — a test class that calls no module included — and so
496
+ did the run of a module that no test calls; the result names the group
497
+ (`FUGR/F`). `run` (`FUNC`) did the same there. The library filters nothing: a
498
+ caller who wants one module's tests reads them out of the result. With an ABAP
499
+ Doc test relation (`"! @testing FUNC:<module>`) on a test class, the default
500
+ scope answered the group's tests as a preview (`isForeign="true"`, nothing
501
+ executed) and `scope: { foreignTests: true }` ran them.
450
502
 
451
503
  **AdtUtils read type safety:**
452
504
  `readObjectMetadata` and `readObjectSource` accept strict object type unions to prevent invalid inputs like `view:ZOBJ`.
@@ -6,6 +6,6 @@ export { AdtLocalDefinitions, type ILocalDefinitionsConfig, } from './AdtLocalDe
6
6
  export { AdtLocalMacros, type ILocalMacrosConfig } from './AdtLocalMacros';
7
7
  export { AdtLocalTestClass, type ILocalTestClassConfig, } from './AdtLocalTestClass';
8
8
  export { AdtLocalTypes, type ILocalTypesConfig } from './AdtLocalTypes';
9
- export { getClassUnitTestResult, getClassUnitTestStatus, IClassUnitTestDefinition, IClassUnitTestRunOptions, startClassUnitTestRun, startClassUnitTestRunByObject, } from './run';
9
+ export { getClassUnitTestResult, getClassUnitTestStatus, IClassUnitTestDefinition, IClassUnitTestRunOptions, startClassUnitTestRun, startClassUnitTestRunByObject, startClassUnitTestRunSync, } from './run';
10
10
  export * from './types';
11
11
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/class/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,GAC9B,MAAM,OAAO,CAAC;AACf,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/class/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EACL,mBAAmB,EACnB,KAAK,uBAAuB,GAC7B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3E,OAAO,EACL,iBAAiB,EACjB,KAAK,qBAAqB,GAC3B,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACxE,OAAO,EACL,sBAAsB,EACtB,sBAAsB,EACtB,wBAAwB,EACxB,wBAAwB,EACxB,qBAAqB,EACrB,6BAA6B,EAC7B,yBAAyB,GAC1B,MAAM,OAAO,CAAC;AACf,cAAc,SAAS,CAAC"}
@@ -17,7 +17,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
17
17
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
18
18
  };
19
19
  Object.defineProperty(exports, "__esModule", { value: true });
20
- exports.startClassUnitTestRunByObject = exports.startClassUnitTestRun = exports.getClassUnitTestStatus = exports.getClassUnitTestResult = exports.AdtLocalTypes = exports.AdtLocalTestClass = exports.AdtLocalMacros = exports.AdtLocalDefinitions = exports.AdtClass = void 0;
20
+ exports.startClassUnitTestRunSync = exports.startClassUnitTestRunByObject = exports.startClassUnitTestRun = exports.getClassUnitTestStatus = exports.getClassUnitTestResult = exports.AdtLocalTypes = exports.AdtLocalTestClass = exports.AdtLocalMacros = exports.AdtLocalDefinitions = exports.AdtClass = void 0;
21
21
  var AdtClass_1 = require("./AdtClass");
22
22
  Object.defineProperty(exports, "AdtClass", { enumerable: true, get: function () { return AdtClass_1.AdtClass; } });
23
23
  var AdtLocalDefinitions_1 = require("./AdtLocalDefinitions");
@@ -33,4 +33,5 @@ Object.defineProperty(exports, "getClassUnitTestResult", { enumerable: true, get
33
33
  Object.defineProperty(exports, "getClassUnitTestStatus", { enumerable: true, get: function () { return run_1.getClassUnitTestStatus; } });
34
34
  Object.defineProperty(exports, "startClassUnitTestRun", { enumerable: true, get: function () { return run_1.startClassUnitTestRun; } });
35
35
  Object.defineProperty(exports, "startClassUnitTestRunByObject", { enumerable: true, get: function () { return run_1.startClassUnitTestRunByObject; } });
36
+ Object.defineProperty(exports, "startClassUnitTestRunSync", { enumerable: true, get: function () { return run_1.startClassUnitTestRunSync; } });
36
37
  __exportStar(require("./types"), exports);
@@ -61,4 +61,15 @@ export declare const getClassUnitTestResult: typeof getUnitTestRunResult;
61
61
  * container runs without the caller naming one.
62
62
  */
63
63
  export declare function startClassUnitTestRunByObject(connection: IAbapConnection, className: string, options?: IClassUnitTestRunOptions): Promise<IAdtWireResponse>;
64
+ /**
65
+ * Run the ABAP Unit tests of whole classes and answer the finished result —
66
+ * `POST /sap/bc/adt/abapunit/testruns`, one request, no run to poll. The
67
+ * request is `startUnitTestRunSync` (`core/shared/abapUnit`), given each
68
+ * class's URI; see there for the format and what was measured.
69
+ *
70
+ * The regular runner's `runSync` and the legacy runner's `run` both send it.
71
+ * `options` absent sends no `<options>` element — the body the legacy runner
72
+ * has always sent, unchanged.
73
+ */
74
+ export declare function startClassUnitTestRunSync(connection: IAbapConnection, classNames: string[], options?: IClassUnitTestRunOptions): Promise<IAdtWireResponse>;
64
75
  //# sourceMappingURL=run.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/core/class/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAIjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,OAAc,EACxB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAoB3B;AAOD,YAAY,EACV,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAErB,MAAM,oBAAoB,CAAC;AAE5B,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,wBAAwB,EAAE,EACjC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA6C3B;AAED,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,6BAAuB,CAAC;AAE3D,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,6BAAuB,CAAC;AAE3D;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAM3B"}
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../../src/core/class/run.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAKjD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAsB,QAAQ,CAC5B,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,EACjB,QAAQ,GAAE,OAAc,EACxB,UAAU,CAAC,EAAE,MAAM,EACnB,QAAQ,CAAC,EAAE,YAAY,GACtB,OAAO,CAAC,gBAAgB,CAAC,CAoB3B;AAOD,YAAY,EACV,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,8BAA8B,CAAC;AAMtC,OAAO,KAAK,EACV,wBAAwB,EACxB,wBAAwB,EACzB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EACL,oBAAoB,EACpB,oBAAoB,EAGrB,MAAM,oBAAoB,CAAC;AAE5B,wBAAsB,qBAAqB,CACzC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,wBAAwB,EAAE,EACjC,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA6C3B;AAED,mFAAmF;AACnF,eAAO,MAAM,sBAAsB,6BAAuB,CAAC;AAE3D,qEAAqE;AACrE,eAAO,MAAM,sBAAsB,6BAAuB,CAAC;AAE3D;;;;GAIG;AACH,wBAAsB,6BAA6B,CACjD,UAAU,EAAE,eAAe,EAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AAMD;;;;;;;;;GASG;AACH,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CAM3B"}
@@ -7,6 +7,8 @@ exports.getClassUnitTestResult = exports.getClassUnitTestStatus = void 0;
7
7
  exports.runClass = runClass;
8
8
  exports.startClassUnitTestRun = startClassUnitTestRun;
9
9
  exports.startClassUnitTestRunByObject = startClassUnitTestRunByObject;
10
+ exports.startClassUnitTestRunSync = startClassUnitTestRunSync;
11
+ const objects_1 = require("../../endpoints/objects");
10
12
  const passport_1 = require("../../runtime/debugger/passport");
11
13
  const xml_1 = require("../../utils/xml");
12
14
  /**
@@ -126,3 +128,19 @@ exports.getClassUnitTestResult = abapUnit_1.getUnitTestRunResult;
126
128
  async function startClassUnitTestRunByObject(connection, className, options) {
127
129
  return (0, abapUnit_1.startUnitTestRunByObject)(connection, { name: className, type: 'CLAS' }, options);
128
130
  }
131
+ // =============================================================================
132
+ // The synchronous runner: /abapunit/testruns
133
+ // =============================================================================
134
+ /**
135
+ * Run the ABAP Unit tests of whole classes and answer the finished result —
136
+ * `POST /sap/bc/adt/abapunit/testruns`, one request, no run to poll. The
137
+ * request is `startUnitTestRunSync` (`core/shared/abapUnit`), given each
138
+ * class's URI; see there for the format and what was measured.
139
+ *
140
+ * The regular runner's `runSync` and the legacy runner's `run` both send it.
141
+ * `options` absent sends no `<options>` element — the body the legacy runner
142
+ * has always sent, unchanged.
143
+ */
144
+ async function startClassUnitTestRunSync(connection, classNames, options) {
145
+ return (0, abapUnit_1.startUnitTestRunSync)(connection, classNames.map((name) => objects_1.CLASS.uri(name)), options);
146
+ }
@@ -29,4 +29,50 @@ export declare function getUnitTestRunResult(connection: IAbapConnection, runId:
29
29
  withNavigationUris?: boolean;
30
30
  format?: 'abapunit' | 'junit';
31
31
  }): Promise<IAdtWireResponse>;
32
+ /**
33
+ * Run the ABAP Unit tests of whole objects and answer the finished result —
34
+ * `POST /sap/bc/adt/abapunit/testruns`, one request, no run to poll. The
35
+ * objects are named by their ADT URIs: a class, a report, a function group, a
36
+ * function module.
37
+ *
38
+ * The one implementation of this endpoint: every runner's `runSync`, and the
39
+ * legacy class runner's `run`, send it.
40
+ *
41
+ * **Measured:** synchronous on a modern and a legacy on-prem system, over HTTP
42
+ * and over RFC — `<aunit:runResult>` in the POST's answer, no `Location` — and
43
+ * the typed and `application/xml` bodies byte-identical; the legacy system
44
+ * ignores a typed `Accept` and answers `application/xml` either way. Advertised
45
+ * (2026-10-22) by an on-prem system and an ABAP Cloud system alike, beside
46
+ * `/abapunit/runs`; and on an on-prem S/4HANA 2023 that has no `/runs` at all
47
+ * (fr0ster/mcp-abap-adt#286).
48
+ *
49
+ * **`<options>` decides whether anything runs for a report or a function
50
+ * group.** Measured on premise (SAP_BASIS 816, 2026-10-23): with `<options>`, a
51
+ * report (test class in its own source or in an include it pulls in), a
52
+ * function group and a function module each ran the same tests with the same
53
+ * alerts as `/abapunit/runs`; the same body without `<options>` answered `200`
54
+ * with an empty `<aunit:runResult/>` for all four. An include's own URI
55
+ * answered empty even with `<options>` — its tests run through the report. So
56
+ * every runner but the legacy class runner sends `<options>`.
57
+ *
58
+ * **Reading the result: `kind` carries the distinction, `severity` does not.**
59
+ * A failed assertion and an uncaught exception both come back
60
+ * `severity="critical"`, so a parser classifying on severity reports a short
61
+ * dump as a failed test. `kind` separates them: `failedAssertion`,
62
+ * `exception`, `noTestClasses`.
63
+ *
64
+ * The format differs from `/runs`:
65
+ * - root `aunit:runConfiguration` in `http://www.sap.com/adt/aunit` (not
66
+ * `aunit:run` in `http://www.sap.com/adt/api/aunit`);
67
+ * - objects by URI in `adtcore:objectReferences` — so a run covers whole
68
+ * objects: the format has no way to name one test class inside its
69
+ * container;
70
+ * - `application/xml` for `Content-Type` and `Accept`.
71
+ *
72
+ * `options` absent sends no `<options>` element — the body the legacy class
73
+ * runner has always sent, unchanged. Given (`{}` included), the scope, risk
74
+ * levels and durations go in `<options>` with the same defaults `/runs` gets;
75
+ * `title` and `context` have no place in this format and are not sent.
76
+ */
77
+ export declare function startUnitTestRunSync(connection: IAbapConnection, objectUris: string[], options?: IClassUnitTestRunOptions): Promise<IAdtWireResponse>;
32
78
  //# sourceMappingURL=abapUnit.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"abapUnit.d.ts","sourceRoot":"","sources":["../../../src/core/shared/abapUnit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAajD,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wDAAwD;AACxD,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA2C3B;AAED,kBAAkB;AAClB,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAU3B;AAED,wCAAwC;AACxC,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAA;CAAE,GACxE,OAAO,CAAC,gBAAgB,CAAC,CAkB3B"}
1
+ {"version":3,"file":"abapUnit.d.ts","sourceRoot":"","sources":["../../../src/core/shared/abapUnit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AAC7E,OAAO,KAAK,EACV,eAAe,EACf,gBAAgB,EACjB,MAAM,yCAAyC,CAAC;AAajD,6DAA6D;AAC7D,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wDAAwD;AACxD,wBAAsB,wBAAwB,CAC5C,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA2C3B;AAED,kBAAkB;AAClB,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAU3B;AAED,wCAAwC;AACxC,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE;IAAE,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,UAAU,GAAG,OAAO,CAAA;CAAE,GACxE,OAAO,CAAC,gBAAgB,CAAC,CAkB3B;AASD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,wBAAwB,GACjC,OAAO,CAAC,gBAAgB,CAAC,CA8B3B"}
@@ -17,6 +17,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
17
17
  exports.startUnitTestRunByObject = startUnitTestRunByObject;
18
18
  exports.getUnitTestRunStatus = getUnitTestRunStatus;
19
19
  exports.getUnitTestRunResult = getUnitTestRunResult;
20
+ exports.startUnitTestRunSync = startUnitTestRunSync;
20
21
  const contentTypes_1 = require("../../constants/contentTypes");
21
22
  const xml_1 = require("../../utils/xml");
22
23
  function boolAttr(value, fallback) {
@@ -95,3 +96,100 @@ async function getUnitTestRunResult(connection, runId, options) {
95
96
  },
96
97
  });
97
98
  }
99
+ // =============================================================================
100
+ // The synchronous runner: /abapunit/testruns
101
+ // =============================================================================
102
+ const CT_TESTRUNS = 'application/xml';
103
+ const ACCEPT_TESTRUNS = 'application/xml';
104
+ /**
105
+ * Run the ABAP Unit tests of whole objects and answer the finished result —
106
+ * `POST /sap/bc/adt/abapunit/testruns`, one request, no run to poll. The
107
+ * objects are named by their ADT URIs: a class, a report, a function group, a
108
+ * function module.
109
+ *
110
+ * The one implementation of this endpoint: every runner's `runSync`, and the
111
+ * legacy class runner's `run`, send it.
112
+ *
113
+ * **Measured:** synchronous on a modern and a legacy on-prem system, over HTTP
114
+ * and over RFC — `<aunit:runResult>` in the POST's answer, no `Location` — and
115
+ * the typed and `application/xml` bodies byte-identical; the legacy system
116
+ * ignores a typed `Accept` and answers `application/xml` either way. Advertised
117
+ * (2026-10-22) by an on-prem system and an ABAP Cloud system alike, beside
118
+ * `/abapunit/runs`; and on an on-prem S/4HANA 2023 that has no `/runs` at all
119
+ * (fr0ster/mcp-abap-adt#286).
120
+ *
121
+ * **`<options>` decides whether anything runs for a report or a function
122
+ * group.** Measured on premise (SAP_BASIS 816, 2026-10-23): with `<options>`, a
123
+ * report (test class in its own source or in an include it pulls in), a
124
+ * function group and a function module each ran the same tests with the same
125
+ * alerts as `/abapunit/runs`; the same body without `<options>` answered `200`
126
+ * with an empty `<aunit:runResult/>` for all four. An include's own URI
127
+ * answered empty even with `<options>` — its tests run through the report. So
128
+ * every runner but the legacy class runner sends `<options>`.
129
+ *
130
+ * **Reading the result: `kind` carries the distinction, `severity` does not.**
131
+ * A failed assertion and an uncaught exception both come back
132
+ * `severity="critical"`, so a parser classifying on severity reports a short
133
+ * dump as a failed test. `kind` separates them: `failedAssertion`,
134
+ * `exception`, `noTestClasses`.
135
+ *
136
+ * The format differs from `/runs`:
137
+ * - root `aunit:runConfiguration` in `http://www.sap.com/adt/aunit` (not
138
+ * `aunit:run` in `http://www.sap.com/adt/api/aunit`);
139
+ * - objects by URI in `adtcore:objectReferences` — so a run covers whole
140
+ * objects: the format has no way to name one test class inside its
141
+ * container;
142
+ * - `application/xml` for `Content-Type` and `Accept`.
143
+ *
144
+ * `options` absent sends no `<options>` element — the body the legacy class
145
+ * runner has always sent, unchanged. Given (`{}` included), the scope, risk
146
+ * levels and durations go in `<options>` with the same defaults `/runs` gets;
147
+ * `title` and `context` have no place in this format and are not sent.
148
+ */
149
+ async function startUnitTestRunSync(connection, objectUris, options) {
150
+ const objectRefs = objectUris
151
+ .map((uri) => {
152
+ return ` <adtcore:objectReference adtcore:uri="${(0, xml_1.escapeXmlAttr)(uri)}"/>`;
153
+ })
154
+ .join('\n');
155
+ const xml = `<?xml version="1.0" encoding="UTF-8"?><aunit:runConfiguration xmlns:aunit="http://www.sap.com/adt/aunit">
156
+ <external>
157
+ <coverage active="false"/>
158
+ </external>
159
+ ${options ? testRunsOptions(options) : ''} <adtcore:objectSets xmlns:adtcore="http://www.sap.com/adt/core">
160
+ <objectSet kind="inclusive">
161
+ <adtcore:objectReferences>
162
+ ${objectRefs}
163
+ </adtcore:objectReferences>
164
+ </objectSet>
165
+ </adtcore:objectSets>
166
+ </aunit:runConfiguration>`;
167
+ return connection.makeAdtRequest({
168
+ url: '/sap/bc/adt/abapunit/testruns',
169
+ method: 'POST',
170
+ timeout: 0,
171
+ data: xml,
172
+ headers: {
173
+ 'Content-Type': CT_TESTRUNS,
174
+ Accept: ACCEPT_TESTRUNS,
175
+ },
176
+ });
177
+ }
178
+ /**
179
+ * `<options>` of a `runConfiguration`, as Eclipse sends it. The scope's three
180
+ * flags are `testDeterminationStrategy`'s: own tests are `sameProgram`,
181
+ * foreign tests `assignedTests`, their preview `appendAssignedTestsPreview`.
182
+ */
183
+ function testRunsOptions(options) {
184
+ const scope = options.scope ?? {};
185
+ const risk = options.riskLevel ?? {};
186
+ const duration = options.duration ?? {};
187
+ return ` <options>
188
+ <uriType value="semantic"/>
189
+ <testDeterminationStrategy sameProgram="${boolAttr(scope.ownTests, true)}" assignedTests="${boolAttr(scope.foreignTests, false)}" appendAssignedTestsPreview="${boolAttr(scope.addForeignTestsAsPreview, true)}"/>
190
+ <testRiskLevels harmless="${boolAttr(risk.harmless, true)}" dangerous="${boolAttr(risk.dangerous, true)}" critical="${boolAttr(risk.critical, true)}"/>
191
+ <testDurations short="${boolAttr(duration.short, true)}" medium="${boolAttr(duration.medium, true)}" long="${boolAttr(duration.long, true)}"/>
192
+ <withNavigationUri enabled="true"/>
193
+ </options>
194
+ `;
195
+ }
@@ -39,6 +39,15 @@ export declare abstract class AbapUnitRunner<R extends IAbapUnitRunnerResults> i
39
39
  constructor(connection: IAbapConnection, logger: ILogger | undefined, results: R);
40
40
  /** Start a run of every test class the one named object holds. */
41
41
  protected startByObject<E extends IAdtError>(name: string, type: string, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
42
+ /**
43
+ * Run the tests of whole objects, named by their ADT URIs, and answer the
44
+ * finished result: one POST to `/abapunit/testruns`. Always with
45
+ * `<options>` — without it a report's, a function group's and a function
46
+ * module's run answered an empty result (see `core/shared/abapUnit`). The
47
+ * answer is the result document, so it is read by `result`, the strategy
48
+ * `getResult` uses; `options.analyse` judges it.
49
+ */
50
+ protected startSync<E extends IAdtError>(objectUris: string[], options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
42
51
  /**
43
52
  * Poll a run. Takes the run it is about: nothing here remembers the last one
44
53
  * started, because ADT does not either — any holder of the id may ask.
@@ -1 +1 @@
1
- {"version":3,"file":"abapUnitRunner.d.ts","sourceRoot":"","sources":["../../src/executors/abapUnitRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAS9D,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAC1C,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB;;;;CAIF,CAAC;AAEnC,8BAAsB,cAAc,CAAC,CAAC,SAAS,sBAAsB,CACnE,YACE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAG5B,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,OAAO,EAAE,CAAC;IAOZ,kEAAkE;IAClE,SAAS,CAAC,aAAa,CAAC,CAAC,SAAS,SAAS,EACzC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQjD;;;OAGG;IACG,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC7C,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,OAAO,GAAG,SAAgB,EAC3C,OAAO,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IASpD,6CAA6C;IACvC,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC7C,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,sBAAsB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACvD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAOrD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EACpD,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAMpB"}
1
+ {"version":3,"file":"abapUnitRunner.d.ts","sourceRoot":"","sources":["../../src/executors/abapUnitRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,wBAAwB,EACxB,eAAe,EACf,mBAAmB,EACnB,sBAAsB,EACvB,MAAM,8BAA8B,CAAC;AAEtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAU9D,gFAAgF;AAChF,MAAM,WAAW,sBAAsB;IACrC,mFAAmF;IACnF,QAAQ,CAAC,GAAG,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IACvC,kCAAkC;IAClC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;IAC1C,qDAAqD;IACrD,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;CAC3C;AAED;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB;;;;CAIF,CAAC;AAEnC,8BAAsB,cAAc,CAAC,CAAC,SAAS,sBAAsB,CACnE,YACE,mBAAmB,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEvE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,eAAe,CAAC;IAC/C,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC;IACpC,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;gBAG5B,UAAU,EAAE,eAAe,EAC3B,MAAM,EAAE,OAAO,GAAG,SAAS,EAC3B,OAAO,EAAE,CAAC;IAOZ,kEAAkE;IAClE,SAAS,CAAC,aAAa,CAAC,CAAC,SAAS,SAAS,EACzC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQjD;;;;;;;OAOG;IACH,SAAS,CAAC,SAAS,CAAC,CAAC,SAAS,SAAS,EACrC,UAAU,EAAE,MAAM,EAAE,EACpB,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAWpD;;;OAGG;IACG,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC7C,KAAK,EAAE,MAAM,EACb,eAAe,GAAE,OAAO,GAAG,SAAgB,EAC3C,OAAO,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAC9B,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IASpD,6CAA6C;IACvC,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC7C,KAAK,EAAE,MAAM,EACb,OAAO,CAAC,EAAE,sBAAsB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACvD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAOrD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EACpD,IAAI,EAAE,MAAM,GACX,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,CAMpB"}
@@ -41,6 +41,20 @@ class AbapUnitRunner {
41
41
  startByObject(name, type, options) {
42
42
  return (0, adtResponse_1.answering)(() => (0, abapUnit_1.startUnitTestRunByObject)(this.connection, { name, type }, options), this.results.run, options?.analyse);
43
43
  }
44
+ /**
45
+ * Run the tests of whole objects, named by their ADT URIs, and answer the
46
+ * finished result: one POST to `/abapunit/testruns`. Always with
47
+ * `<options>` — without it a report's, a function group's and a function
48
+ * module's run answered an empty result (see `core/shared/abapUnit`). The
49
+ * answer is the result document, so it is read by `result`, the strategy
50
+ * `getResult` uses; `options.analyse` judges it.
51
+ */
52
+ startSync(objectUris, options) {
53
+ // `runOptions` is an object even when the caller gave none, so the
54
+ // `<options>` element is always sent.
55
+ const { analyse, ...runOptions } = options ?? {};
56
+ return (0, adtResponse_1.answering)(() => (0, abapUnit_1.startUnitTestRunSync)(this.connection, objectUris, runOptions), this.results.result, analyse);
57
+ }
44
58
  /**
45
59
  * Poll a run. Takes the run it is about: nothing here remembers the last one
46
60
  * started, because ADT does not either — any holder of the id may ask.
@@ -27,7 +27,12 @@ import { AbapUnitRunner, type IAbapUnitRunnerResults } from '../abapUnitRunner';
27
27
  * whose every test class runs.
28
28
  */
29
29
  export type IClassTestRunTarget = IClassUnitTestDefinition[] | string;
30
- /** One strategy per distinct answer: starting a run, polling it, its result. */
30
+ /** The distinct containers a target names: what `/testruns` addresses. */
31
+ export declare function containersOf(target: IClassTestRunTarget): string[];
32
+ /**
33
+ * One strategy per distinct answer: starting a run, polling it, its result.
34
+ * `runSync` answers the result document itself, so it is read by `result`.
35
+ */
31
36
  export type IClassTestRunnerResults = IAbapUnitRunnerResults;
32
37
  /** The shipped default: documents as they arrived. */
33
38
  export declare const classTestRunnerDocuments: {
@@ -49,5 +54,26 @@ export declare class ClassTestRunner<R extends IClassTestRunnerResults = typeof
49
54
  * read as a failure.
50
55
  */
51
56
  run<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
57
+ /**
58
+ * Run the tests and answer the finished result. One POST, to
59
+ * `/sap/bc/adt/abapunit/testruns` — the synchronous runner, beside the
60
+ * asynchronous `run` + `getStatus` + `getResult`, which stays the default.
61
+ *
62
+ * An explicit choice of the caller's: nothing here asks the system which
63
+ * runner it has. A system without `/abapunit/runs` (an on-prem S/4HANA 2023
64
+ * was measured with `/testruns` alone) needs this one; whether a system has
65
+ * it is in its discovery, which is the caller's to read.
66
+ *
67
+ * The answer is the `aunit:runResult` document, so it is read by this
68
+ * runner's `result` strategy — the one `getResult` uses — and a failing test
69
+ * is in it as an `alert`; whether that is a failure is `options.analyse`'s
70
+ * (`analyseUnitTest` from @mcp-abap-adt/adt-strategies reads it so).
71
+ *
72
+ * Differences from `run`: the endpoint addresses whole classes, so a target
73
+ * of test definitions runs each distinct container whole, and `title` and
74
+ * `context` are not sent; scope, risk levels and durations are, with the
75
+ * same defaults.
76
+ */
77
+ runSync<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
52
78
  }
53
79
  //# sourceMappingURL=ClassTestRunner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ClassTestRunner.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAG9D,OAAO,EACL,cAAc,EAEd,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,EAAE,GAAG,MAAM,CAAC;AAEtE,gFAAgF;AAChF,MAAM,MAAM,uBAAuB,GAAG,sBAAsB,CAAC;AAE7D,sDAAsD;AACtD,eAAO,MAAM,wBAAwB;;;;CAA0B,CAAC;AAEhE,qBAAa,eAAe,CACxB,CAAC,SAAS,uBAAuB,GAAG,OAAO,wBAAwB,CAErE,SAAQ,cAAc,CAAC,CAAC,CACxB,YACE,YAAY,CACV,mBAAmB,EACnB,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EACpB,wBAAwB,CACzB;gBAGD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAEhB,OAAO,GAAE,CAA4C;IAKvD;;;;;;;;;;OAUG;IACG,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAUlD"}
1
+ {"version":3,"file":"ClassTestRunner.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACxB,wBAAwB,EACxB,eAAe,EAChB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAM9D,OAAO,EACL,cAAc,EAEd,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAC;AAE3B;;;GAGG;AACH,MAAM,MAAM,mBAAmB,GAAG,wBAAwB,EAAE,GAAG,MAAM,CAAC;AAEtE,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,MAAM,EAAE,CAIlE;AAED;;;GAGG;AACH,MAAM,MAAM,uBAAuB,GAAG,sBAAsB,CAAC;AAE7D,sDAAsD;AACtD,eAAO,MAAM,wBAAwB;;;;CAA0B,CAAC;AAEhE,qBAAa,eAAe,CACxB,CAAC,SAAS,uBAAuB,GAAG,OAAO,wBAAwB,CAErE,SAAQ,cAAc,CAAC,CAAC,CACxB,YACE,YAAY,CACV,mBAAmB,EACnB,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EACpB,wBAAwB,CACzB;gBAGD,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAEhB,OAAO,GAAE,CAA4C;IAKvD;;;;;;;;;;OAUG;IACG,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvC,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAWjD;;;;;;;;;;;;;;;;;;;OAmBG;IACG,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC3C,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAarD"}
@@ -21,9 +21,16 @@
21
21
  */
22
22
  Object.defineProperty(exports, "__esModule", { value: true });
23
23
  exports.ClassTestRunner = exports.classTestRunnerDocuments = void 0;
24
+ exports.containersOf = containersOf;
24
25
  const run_1 = require("../../core/class/run");
25
26
  const adtResponse_1 = require("../../utils/adtResponse");
26
27
  const abapUnitRunner_1 = require("../abapUnitRunner");
28
+ /** The distinct containers a target names: what `/testruns` addresses. */
29
+ function containersOf(target) {
30
+ return typeof target === 'string'
31
+ ? [target]
32
+ : [...new Set(target.map((test) => test.containerClass))];
33
+ }
27
34
  /** The shipped default: documents as they arrived. */
28
35
  exports.classTestRunnerDocuments = abapUnitRunner_1.abapUnitRunnerDocuments;
29
36
  class ClassTestRunner extends abapUnitRunner_1.AbapUnitRunner {
@@ -49,5 +56,29 @@ class ClassTestRunner extends abapUnitRunner_1.AbapUnitRunner {
49
56
  }
50
57
  return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRun)(this.connection, target, options), this.results.run, options?.analyse);
51
58
  }
59
+ /**
60
+ * Run the tests and answer the finished result. One POST, to
61
+ * `/sap/bc/adt/abapunit/testruns` — the synchronous runner, beside the
62
+ * asynchronous `run` + `getStatus` + `getResult`, which stays the default.
63
+ *
64
+ * An explicit choice of the caller's: nothing here asks the system which
65
+ * runner it has. A system without `/abapunit/runs` (an on-prem S/4HANA 2023
66
+ * was measured with `/testruns` alone) needs this one; whether a system has
67
+ * it is in its discovery, which is the caller's to read.
68
+ *
69
+ * The answer is the `aunit:runResult` document, so it is read by this
70
+ * runner's `result` strategy — the one `getResult` uses — and a failing test
71
+ * is in it as an `alert`; whether that is a failure is `options.analyse`'s
72
+ * (`analyseUnitTest` from @mcp-abap-adt/adt-strategies reads it so).
73
+ *
74
+ * Differences from `run`: the endpoint addresses whole classes, so a target
75
+ * of test definitions runs each distinct container whole, and `title` and
76
+ * `context` are not sent; scope, risk levels and durations are, with the
77
+ * same defaults.
78
+ */
79
+ async runSync(target, options) {
80
+ const { analyse, ...runOptions } = options ?? {};
81
+ return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRunSync)(this.connection, containersOf(target), runOptions), this.results.result, analyse);
82
+ }
52
83
  }
53
84
  exports.ClassTestRunner = ClassTestRunner;
@@ -21,6 +21,12 @@ export declare class ClassTestRunnerLegacy<R extends IClassTestRunnerResults = t
21
21
  * result document itself, not an id.
22
22
  */
23
23
  run<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
24
+ /**
25
+ * The same request as `run` — on a legacy system `run` is already the
26
+ * synchronous one — answered through the `result` strategy, as the regular
27
+ * runner's `runSync` is.
28
+ */
29
+ runSync<E extends IAdtError = IAdtError>(target: IClassTestRunTarget, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
24
30
  /**
25
31
  * Refused without a request: a legacy system finishes a run before it
26
32
  * answers and exposes no run to poll. `run`'s own answer is the result.
@@ -1 +1 @@
1
- {"version":3,"file":"ClassTestRunnerLegacy.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunnerLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,wBAAwB,EAEzB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EACL,eAAe,EACf,KAAK,wBAAwB,EAC7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,qBAAqB,CAChC,CAAC,SAAS,uBAAuB,GAAG,OAAO,wBAAwB,CACnE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC1B;;;;;OAKG;IACY,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAChD,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAYjD;;;OAGG;IACY,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;IASD,0EAA0E;IAC3D,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;CAQF"}
1
+ {"version":3,"file":"ClassTestRunnerLegacy.d.ts","sourceRoot":"","sources":["../../../src/executors/class/ClassTestRunnerLegacy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,wBAAwB,EAEzB,MAAM,8BAA8B,CAAC;AAItC,OAAO,EACL,eAAe,EACf,KAAK,wBAAwB,EAE7B,KAAK,uBAAuB,EAC5B,KAAK,mBAAmB,EACzB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,qBAAqB,CAChC,CAAC,SAAS,uBAAuB,GAAG,OAAO,wBAAwB,CACnE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC1B;;;;;OAKG;IACY,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAChD,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAUjD;;;;OAIG;IACY,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACpD,MAAM,EAAE,mBAAmB,EAC3B,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAQpD;;;OAGG;IACY,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;IASD,0EAA0E;IAC3D,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;CAQF"}
@@ -15,7 +15,7 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.ClassTestRunnerLegacy = void 0;
17
17
  const interfaces_adt_1 = require("@mcp-abap-adt/interfaces-adt");
18
- const runLegacy_1 = require("../../core/class/runLegacy");
18
+ const run_1 = require("../../core/class/run");
19
19
  const adtResponse_1 = require("../../utils/adtResponse");
20
20
  const ClassTestRunner_1 = require("./ClassTestRunner");
21
21
  class ClassTestRunnerLegacy extends ClassTestRunner_1.ClassTestRunner {
@@ -26,10 +26,17 @@ class ClassTestRunnerLegacy extends ClassTestRunner_1.ClassTestRunner {
26
26
  * result document itself, not an id.
27
27
  */
28
28
  async run(target, options) {
29
- const classNames = typeof target === 'string'
30
- ? [target]
31
- : [...new Set(target.map((test) => test.containerClass))];
32
- return (0, adtResponse_1.answering)(() => (0, runLegacy_1.startClassUnitTestRunLegacy)(this.connection, classNames), this.results.run, options?.analyse);
29
+ // No options: the body a legacy system has always been sent — the
30
+ // `<options>` element `runSync` sends is unmeasured there.
31
+ return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRunSync)(this.connection, (0, ClassTestRunner_1.containersOf)(target)), this.results.run, options?.analyse);
32
+ }
33
+ /**
34
+ * The same request as `run` — on a legacy system `run` is already the
35
+ * synchronous one — answered through the `result` strategy, as the regular
36
+ * runner's `runSync` is.
37
+ */
38
+ async runSync(target, options) {
39
+ return (0, adtResponse_1.answering)(() => (0, run_1.startClassUnitTestRunSync)(this.connection, (0, ClassTestRunner_1.containersOf)(target)), this.results.result, options?.analyse);
33
40
  }
34
41
  /**
35
42
  * Refused without a request: a legacy system finishes a run before it
@@ -9,6 +9,11 @@
9
9
  * `osl:object type="FUGR"` ran all seven test methods of a group whose test
10
10
  * include covers two test classes. Running one module's tests only is
11
11
  * `FunctionModuleTestRunner`.
12
+ *
13
+ * Measured on premise (SAP_BASIS 816, 2026-10-23): `/abapunit/testruns` given
14
+ * the group's URI runs the same tests with the same alerts as `/runs` — with
15
+ * the Eclipse-style `<options>` only; without it, an empty result. `runSync`
16
+ * always sends `<options>`.
12
17
  */
13
18
  import type { IAdtAnalyseOptions, IAdtError, IAdtResponse, IAdtRunnable, IClassUnitTestRunOptions } from '@mcp-abap-adt/interfaces-adt';
14
19
  import type { IAbapConnection } from '@mcp-abap-adt/interfaces-adt-connection';
@@ -24,13 +29,32 @@ export declare class FunctionGroupTestRunner<R extends IFunctionGroupTestRunnerR
24
29
  constructor(connection: IAbapConnection, logger?: ILogger, results?: R);
25
30
  /** Run every test class of the group. One POST. */
26
31
  run<E extends IAdtError = IAdtError>(functionGroupName: string, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
32
+ /**
33
+ * Run every test class of the group and answer the finished result. One
34
+ * POST, to `/sap/bc/adt/abapunit/testruns` — the synchronous runner, beside
35
+ * the asynchronous `run` + `getStatus` + `getResult`, which stays the
36
+ * default.
37
+ *
38
+ * An explicit choice of the caller's: nothing here asks the system which
39
+ * runner it has. The group is named by its URI and the run configuration
40
+ * always carries `<options>` (scope, risk levels and durations, with `run`'s
41
+ * defaults) — without it the endpoint answered an empty result for a group
42
+ * with tests. `title` and `context` are not sent.
43
+ *
44
+ * The answer is the `aunit:runResult` document, read by this runner's
45
+ * `result` strategy; whether a failing test is a failure is
46
+ * `options.analyse`'s.
47
+ */
48
+ runSync<E extends IAdtError = IAdtError>(functionGroupName: string, options?: IClassUnitTestRunOptions & IAdtAnalyseOptions<E>): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
27
49
  }
28
50
  /**
29
51
  * Below 7.50: refused without a request, as a report's run is — the legacy
30
- * endpoint has not been measured to find a group's tests.
52
+ * endpoint has not been measured to find a group's tests, with `<options>` or
53
+ * without. `runSync` is refused the same way.
31
54
  */
32
55
  export declare class FunctionGroupTestRunnerLegacy<R extends IFunctionGroupTestRunnerResults = typeof functionGroupTestRunnerDocuments> extends FunctionGroupTestRunner<R> {
33
56
  run<E extends IAdtError = IAdtError>(): Promise<IAdtResponse<ReturnType<R['run']>, E>>;
57
+ runSync<E extends IAdtError = IAdtError>(): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
34
58
  getStatus<E extends IAdtError = IAdtError>(): Promise<IAdtResponse<ReturnType<R['status']>, E>>;
35
59
  getResult<E extends IAdtError = IAdtError>(): Promise<IAdtResponse<ReturnType<R['result']>, E>>;
36
60
  }
@@ -1 +1 @@
1
- {"version":3,"file":"FunctionGroupTestRunner.d.ts","sourceRoot":"","sources":["../../../src/executors/functionGroup/FunctionGroupTestRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EACL,cAAc,EAEd,KAAK,sBAAsB,EAE5B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,+BAA+B,GAAG,sBAAsB,CAAC;AACrE,eAAO,MAAM,gCAAgC;;;;CAA0B,CAAC;AAExE,qBAAa,uBAAuB,CAChC,CAAC,SACC,+BAA+B,GAAG,OAAO,gCAAgC,CAE7E,SAAQ,cAAc,CAAC,CAAC,CACxB,YACE,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC;gBAGpE,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAEhB,OAAO,GAAE,CAAoD;IAK/D,mDAAmD;IAC7C,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvC,iBAAiB,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAGlD;AAED;;;GAGG;AACH,qBAAa,6BAA6B,CACxC,CAAC,SACC,+BAA+B,GAAG,OAAO,gCAAgC,CAC3E,SAAQ,uBAAuB,CAAC,CAAC,CAAC;IACnB,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAC5D,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACtC;IAIc,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;IAIc,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;CAGF"}
1
+ {"version":3,"file":"FunctionGroupTestRunner.d.ts","sourceRoot":"","sources":["../../../src/executors/functionGroup/FunctionGroupTestRunner.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EACV,kBAAkB,EAClB,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,wBAAwB,EACzB,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yCAAyC,CAAC;AAC/E,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,gCAAgC,CAAC;AAE9D,OAAO,EACL,cAAc,EAEd,KAAK,sBAAsB,EAE5B,MAAM,mBAAmB,CAAC;AAE3B,MAAM,MAAM,+BAA+B,GAAG,sBAAsB,CAAC;AACrE,eAAO,MAAM,gCAAgC;;;;CAA0B,CAAC;AAExE,qBAAa,uBAAuB,CAChC,CAAC,SACC,+BAA+B,GAAG,OAAO,gCAAgC,CAE7E,SAAQ,cAAc,CAAC,CAAC,CACxB,YACE,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,wBAAwB,CAAC;gBAGpE,UAAU,EAAE,eAAe,EAC3B,MAAM,CAAC,EAAE,OAAO,EAEhB,OAAO,GAAE,CAAoD;IAK/D,mDAAmD;IAC7C,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EACvC,iBAAiB,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAIjD;;;;;;;;;;;;;;;OAeG;IACG,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,EAC3C,iBAAiB,EAAE,MAAM,EACzB,OAAO,CAAC,EAAE,wBAAwB,GAAG,kBAAkB,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;CAGrD;AAED;;;;GAIG;AACH,qBAAa,6BAA6B,CACxC,CAAC,SACC,+BAA+B,GAAG,OAAO,gCAAgC,CAC3E,SAAQ,uBAAuB,CAAC,CAAC,CAAC;IACnB,GAAG,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAC5D,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CACtC;IAIc,OAAO,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAChE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;IAIc,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;IAIc,SAAS,CAAC,CAAC,SAAS,SAAS,GAAG,SAAS,KAAK,OAAO,CAClE,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CACzC;CAGF"}