@exodus/xqa 6.0.0 → 7.0.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/dist/consumer-api.cjs +182 -123
- package/dist/consumer-api.d.ts +25 -8
- package/dist/consumer-api.mjs +182 -123
- package/dist/xqa.cjs +107407 -72225
- package/package.json +7 -8
package/dist/consumer-api.cjs
CHANGED
|
@@ -261,8 +261,8 @@ var require_index_cjs = __commonJS({
|
|
|
261
261
|
return new Ok(res.value);
|
|
262
262
|
})));
|
|
263
263
|
}
|
|
264
|
-
match(
|
|
265
|
-
return this._promise.then((res) => res.match(
|
|
264
|
+
match(ok6, _err) {
|
|
265
|
+
return this._promise.then((res) => res.match(ok6, _err));
|
|
266
266
|
}
|
|
267
267
|
unwrapOr(t) {
|
|
268
268
|
return this._promise.then((res) => res.unwrapOr(t));
|
|
@@ -301,17 +301,17 @@ var require_index_cjs = __commonJS({
|
|
|
301
301
|
function okAsync(value) {
|
|
302
302
|
return new ResultAsync2(Promise.resolve(new Ok(value)));
|
|
303
303
|
}
|
|
304
|
-
function errAsync2(
|
|
305
|
-
return new ResultAsync2(Promise.resolve(new Err(
|
|
304
|
+
function errAsync2(err6) {
|
|
305
|
+
return new ResultAsync2(Promise.resolve(new Err(err6)));
|
|
306
306
|
}
|
|
307
307
|
var fromPromise = ResultAsync2.fromPromise;
|
|
308
308
|
var fromSafePromise = ResultAsync2.fromSafePromise;
|
|
309
309
|
var fromAsyncThrowable = ResultAsync2.fromThrowable;
|
|
310
310
|
var combineResultList = (resultList) => {
|
|
311
|
-
let acc =
|
|
311
|
+
let acc = ok5([]);
|
|
312
312
|
for (const result of resultList) {
|
|
313
313
|
if (result.isErr()) {
|
|
314
|
-
acc =
|
|
314
|
+
acc = err5(result.error);
|
|
315
315
|
break;
|
|
316
316
|
} else {
|
|
317
317
|
acc.map((list) => list.push(result.value));
|
|
@@ -321,12 +321,12 @@ var require_index_cjs = __commonJS({
|
|
|
321
321
|
};
|
|
322
322
|
var combineResultAsyncList = (asyncResultList) => ResultAsync2.fromSafePromise(Promise.all(asyncResultList)).andThen(combineResultList);
|
|
323
323
|
var combineResultListWithAllErrors = (resultList) => {
|
|
324
|
-
let acc =
|
|
324
|
+
let acc = ok5([]);
|
|
325
325
|
for (const result of resultList) {
|
|
326
326
|
if (result.isErr() && acc.isErr()) {
|
|
327
327
|
acc.error.push(result.error);
|
|
328
328
|
} else if (result.isErr() && acc.isOk()) {
|
|
329
|
-
acc =
|
|
329
|
+
acc = err5([result.error]);
|
|
330
330
|
} else if (result.isOk() && acc.isOk()) {
|
|
331
331
|
acc.value.push(result.value);
|
|
332
332
|
}
|
|
@@ -340,9 +340,9 @@ var require_index_cjs = __commonJS({
|
|
|
340
340
|
return (...args) => {
|
|
341
341
|
try {
|
|
342
342
|
const result = fn(...args);
|
|
343
|
-
return
|
|
343
|
+
return ok5(result);
|
|
344
344
|
} catch (e) {
|
|
345
|
-
return
|
|
345
|
+
return err5(errorFn ? errorFn(e) : e);
|
|
346
346
|
}
|
|
347
347
|
};
|
|
348
348
|
}
|
|
@@ -356,11 +356,11 @@ var require_index_cjs = __commonJS({
|
|
|
356
356
|
}
|
|
357
357
|
Result.combineWithAllErrors = combineWithAllErrors;
|
|
358
358
|
})(exports2.Result || (exports2.Result = {}));
|
|
359
|
-
function
|
|
359
|
+
function ok5(value) {
|
|
360
360
|
return new Ok(value);
|
|
361
361
|
}
|
|
362
|
-
function
|
|
363
|
-
return new Err(
|
|
362
|
+
function err5(err6) {
|
|
363
|
+
return new Err(err6);
|
|
364
364
|
}
|
|
365
365
|
function safeTry(body) {
|
|
366
366
|
const n = body().next();
|
|
@@ -380,11 +380,11 @@ var require_index_cjs = __commonJS({
|
|
|
380
380
|
return !this.isOk();
|
|
381
381
|
}
|
|
382
382
|
map(f) {
|
|
383
|
-
return
|
|
383
|
+
return ok5(f(this.value));
|
|
384
384
|
}
|
|
385
385
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
386
386
|
mapErr(_f) {
|
|
387
|
-
return
|
|
387
|
+
return ok5(this.value);
|
|
388
388
|
}
|
|
389
389
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
390
390
|
andThen(f) {
|
|
@@ -399,14 +399,14 @@ var require_index_cjs = __commonJS({
|
|
|
399
399
|
f(this.value);
|
|
400
400
|
} catch (e) {
|
|
401
401
|
}
|
|
402
|
-
return
|
|
402
|
+
return ok5(this.value);
|
|
403
403
|
}
|
|
404
404
|
orTee(_f) {
|
|
405
|
-
return
|
|
405
|
+
return ok5(this.value);
|
|
406
406
|
}
|
|
407
407
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
408
408
|
orElse(_f) {
|
|
409
|
-
return
|
|
409
|
+
return ok5(this.value);
|
|
410
410
|
}
|
|
411
411
|
asyncAndThen(f) {
|
|
412
412
|
return f(this.value);
|
|
@@ -423,8 +423,8 @@ var require_index_cjs = __commonJS({
|
|
|
423
423
|
return this.value;
|
|
424
424
|
}
|
|
425
425
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
426
|
-
match(
|
|
427
|
-
return
|
|
426
|
+
match(ok6, _err) {
|
|
427
|
+
return ok6(this.value);
|
|
428
428
|
}
|
|
429
429
|
safeUnwrap() {
|
|
430
430
|
const value = this.value;
|
|
@@ -455,27 +455,27 @@ var require_index_cjs = __commonJS({
|
|
|
455
455
|
}
|
|
456
456
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
457
457
|
map(_f) {
|
|
458
|
-
return
|
|
458
|
+
return err5(this.error);
|
|
459
459
|
}
|
|
460
460
|
mapErr(f) {
|
|
461
|
-
return
|
|
461
|
+
return err5(f(this.error));
|
|
462
462
|
}
|
|
463
463
|
andThrough(_f) {
|
|
464
|
-
return
|
|
464
|
+
return err5(this.error);
|
|
465
465
|
}
|
|
466
466
|
andTee(_f) {
|
|
467
|
-
return
|
|
467
|
+
return err5(this.error);
|
|
468
468
|
}
|
|
469
469
|
orTee(f) {
|
|
470
470
|
try {
|
|
471
471
|
f(this.error);
|
|
472
472
|
} catch (e) {
|
|
473
473
|
}
|
|
474
|
-
return
|
|
474
|
+
return err5(this.error);
|
|
475
475
|
}
|
|
476
476
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
477
477
|
andThen(_f) {
|
|
478
|
-
return
|
|
478
|
+
return err5(this.error);
|
|
479
479
|
}
|
|
480
480
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
|
|
481
481
|
orElse(f) {
|
|
@@ -495,13 +495,13 @@ var require_index_cjs = __commonJS({
|
|
|
495
495
|
unwrapOr(v) {
|
|
496
496
|
return v;
|
|
497
497
|
}
|
|
498
|
-
match(_ok,
|
|
499
|
-
return
|
|
498
|
+
match(_ok, err6) {
|
|
499
|
+
return err6(this.error);
|
|
500
500
|
}
|
|
501
501
|
safeUnwrap() {
|
|
502
502
|
const error48 = this.error;
|
|
503
503
|
return (function* () {
|
|
504
|
-
yield
|
|
504
|
+
yield err5(error48);
|
|
505
505
|
throw new Error("Do not use this generator out of `safeTry`");
|
|
506
506
|
})();
|
|
507
507
|
}
|
|
@@ -521,13 +521,13 @@ var require_index_cjs = __commonJS({
|
|
|
521
521
|
exports2.Err = Err;
|
|
522
522
|
exports2.Ok = Ok;
|
|
523
523
|
exports2.ResultAsync = ResultAsync2;
|
|
524
|
-
exports2.err =
|
|
524
|
+
exports2.err = err5;
|
|
525
525
|
exports2.errAsync = errAsync2;
|
|
526
526
|
exports2.fromAsyncThrowable = fromAsyncThrowable;
|
|
527
527
|
exports2.fromPromise = fromPromise;
|
|
528
528
|
exports2.fromSafePromise = fromSafePromise;
|
|
529
529
|
exports2.fromThrowable = fromThrowable3;
|
|
530
|
-
exports2.ok =
|
|
530
|
+
exports2.ok = ok5;
|
|
531
531
|
exports2.okAsync = okAsync;
|
|
532
532
|
exports2.safeTry = safeTry;
|
|
533
533
|
}
|
|
@@ -5320,8 +5320,8 @@ var require_resolve_flow_scalar = __commonJS({
|
|
|
5320
5320
|
};
|
|
5321
5321
|
function parseCharCode(source, offset, length, onError) {
|
|
5322
5322
|
const cc = source.substr(offset, length);
|
|
5323
|
-
const
|
|
5324
|
-
const code =
|
|
5323
|
+
const ok5 = cc.length === length && /^[0-9a-fA-F]+$/.test(cc);
|
|
5324
|
+
const code = ok5 ? parseInt(cc, 16) : NaN;
|
|
5325
5325
|
if (isNaN(code)) {
|
|
5326
5326
|
const raw = source.substr(offset - 2, length + 2);
|
|
5327
5327
|
onError(offset - 2, "BAD_DQ_ESCAPE", `Invalid escape sequence ${raw}`);
|
|
@@ -21736,7 +21736,7 @@ function redactCause(value) {
|
|
|
21736
21736
|
|
|
21737
21737
|
// ../../packages/shared/dist/spec.js
|
|
21738
21738
|
var import_neverthrow3 = __toESM(require_index_cjs(), 1);
|
|
21739
|
-
var ID_REGEX = /^[a-z0-9][a-z0-9-]*(\.[a-z0-9-]
|
|
21739
|
+
var ID_REGEX = /^[a-z0-9][a-z0-9-]*(\.[a-z0-9][a-z0-9-]*)*$/;
|
|
21740
21740
|
var toSpecId = (value) => ID_REGEX.test(value) ? (0, import_neverthrow3.ok)(value) : (0, import_neverthrow3.err)({ type: "CATALOG_INVALID_ID", kind: "spec", id: value });
|
|
21741
21741
|
var toSuiteId = (value) => ID_REGEX.test(value) ? (0, import_neverthrow3.ok)(value) : (0, import_neverthrow3.err)({ type: "CATALOG_INVALID_ID", kind: "suite", id: value });
|
|
21742
21742
|
|
|
@@ -21744,8 +21744,88 @@ var toSuiteId = (value) => ID_REGEX.test(value) ? (0, import_neverthrow3.ok)(val
|
|
|
21744
21744
|
var CATALOG_INTERFACE_VERSION = 1;
|
|
21745
21745
|
|
|
21746
21746
|
// ../../packages/shared/dist/parse-spec-shared.js
|
|
21747
|
-
var
|
|
21747
|
+
var import_neverthrow5 = __toESM(require_index_cjs(), 1);
|
|
21748
21748
|
var yaml = __toESM(require_dist(), 1);
|
|
21749
|
+
|
|
21750
|
+
// ../../packages/shared/dist/parse-spec-steps.js
|
|
21751
|
+
var import_neverthrow4 = __toESM(require_index_cjs(), 1);
|
|
21752
|
+
var STEP_LINE_PATTERN = /^\d+\.\s+(.*)$/;
|
|
21753
|
+
var UNICODE_ARROW = " \u2192 ";
|
|
21754
|
+
var ASCII_ARROW = " -> ";
|
|
21755
|
+
var OPTIONAL_PREFIX = "(optional) ";
|
|
21756
|
+
var HINT_PATTERN = /\s*\[hint:\s*(?:"([^"]*)"|([^\]]+?))\s*\]\s*$/i;
|
|
21757
|
+
var ASSERTION_BULLET = "- ";
|
|
21758
|
+
function splitHint(text) {
|
|
21759
|
+
const match = HINT_PATTERN.exec(text);
|
|
21760
|
+
if (match === null) {
|
|
21761
|
+
return { text: text.trim() };
|
|
21762
|
+
}
|
|
21763
|
+
const hintValue = (match[1] ?? match[2] ?? "").trim();
|
|
21764
|
+
const stripped = text.slice(0, text.length - match[0].length).trim();
|
|
21765
|
+
if (hintValue === "") {
|
|
21766
|
+
return { text: stripped };
|
|
21767
|
+
}
|
|
21768
|
+
return { text: stripped, hint: hintValue };
|
|
21769
|
+
}
|
|
21770
|
+
function splitOptional(raw) {
|
|
21771
|
+
if (raw.startsWith(OPTIONAL_PREFIX)) {
|
|
21772
|
+
return { body: raw.slice(OPTIONAL_PREFIX.length), isOptional: true };
|
|
21773
|
+
}
|
|
21774
|
+
return { body: raw, isOptional: false };
|
|
21775
|
+
}
|
|
21776
|
+
function findArrowIndex(body) {
|
|
21777
|
+
const unicodeIndex = body.indexOf(UNICODE_ARROW);
|
|
21778
|
+
if (unicodeIndex !== -1) {
|
|
21779
|
+
return unicodeIndex;
|
|
21780
|
+
}
|
|
21781
|
+
return body.indexOf(ASCII_ARROW);
|
|
21782
|
+
}
|
|
21783
|
+
function arrowLength(body, arrowIndex) {
|
|
21784
|
+
return body.startsWith(UNICODE_ARROW, arrowIndex) ? UNICODE_ARROW.length : ASCII_ARROW.length;
|
|
21785
|
+
}
|
|
21786
|
+
function buildStepWithoutOutcome({ body, index, isOptional }) {
|
|
21787
|
+
const { text, hint } = splitHint(body);
|
|
21788
|
+
if (hint === void 0) {
|
|
21789
|
+
return { index, intent: text, isOptional };
|
|
21790
|
+
}
|
|
21791
|
+
return { index, intent: text, hint, isOptional };
|
|
21792
|
+
}
|
|
21793
|
+
function buildStepWithOutcome({ intent, remainder, index, isOptional }) {
|
|
21794
|
+
const { text: outcome, hint } = splitHint(remainder);
|
|
21795
|
+
if (hint === void 0) {
|
|
21796
|
+
return { index, intent, outcome, isOptional };
|
|
21797
|
+
}
|
|
21798
|
+
return { index, intent, outcome, hint, isOptional };
|
|
21799
|
+
}
|
|
21800
|
+
function buildStep(raw, index) {
|
|
21801
|
+
const { body, isOptional } = splitOptional(raw);
|
|
21802
|
+
const arrowIndex = findArrowIndex(body);
|
|
21803
|
+
if (arrowIndex === -1) {
|
|
21804
|
+
return buildStepWithoutOutcome({ body, index, isOptional });
|
|
21805
|
+
}
|
|
21806
|
+
const intent = body.slice(0, arrowIndex).trim();
|
|
21807
|
+
const remainder = body.slice(arrowIndex + arrowLength(body, arrowIndex));
|
|
21808
|
+
return buildStepWithOutcome({ intent, remainder, index, isOptional });
|
|
21809
|
+
}
|
|
21810
|
+
function parseStepLine(line, index) {
|
|
21811
|
+
const match = STEP_LINE_PATTERN.exec(line.trim());
|
|
21812
|
+
return match === null ? void 0 : buildStep(match[1] ?? "", index);
|
|
21813
|
+
}
|
|
21814
|
+
function parseSteps(stepsBody) {
|
|
21815
|
+
const steps = stepsBody.split("\n").map((line, index) => parseStepLine(line, index + 1)).filter((step) => step !== void 0);
|
|
21816
|
+
if (steps.length === 0) {
|
|
21817
|
+
return (0, import_neverthrow4.err)({ type: "EMPTY_STEPS_SECTION" });
|
|
21818
|
+
}
|
|
21819
|
+
return (0, import_neverthrow4.ok)(steps);
|
|
21820
|
+
}
|
|
21821
|
+
function parseAssertions(body) {
|
|
21822
|
+
if (body === void 0 || body.trim() === "") {
|
|
21823
|
+
return [];
|
|
21824
|
+
}
|
|
21825
|
+
return body.split("\n").map((line) => line.trim()).filter((line) => line.startsWith(ASSERTION_BULLET)).map((line) => line.slice(ASSERTION_BULLET.length).trim());
|
|
21826
|
+
}
|
|
21827
|
+
|
|
21828
|
+
// ../../packages/shared/dist/parse-spec-shared.js
|
|
21749
21829
|
var FRONTMATTER_OPEN = "---\n";
|
|
21750
21830
|
var FRONTMATTER_CLOSE = "\n---\n";
|
|
21751
21831
|
var FRONTMATTER_EMPTY_CLOSE = "---\n";
|
|
@@ -21756,13 +21836,22 @@ var SECTION_HEADING_PREFIX = "## ";
|
|
|
21756
21836
|
var SETUP_HEADING = "## Setup";
|
|
21757
21837
|
var STEPS_HEADING = "## Steps";
|
|
21758
21838
|
var ASSERTIONS_HEADING = "## Assertions";
|
|
21759
|
-
var
|
|
21760
|
-
var
|
|
21761
|
-
var
|
|
21762
|
-
var
|
|
21763
|
-
|
|
21764
|
-
|
|
21765
|
-
|
|
21839
|
+
var VARIANT_PATTERN = /^##\s+(.+)$/;
|
|
21840
|
+
var URL_PATTERN = /^https?:\/\//;
|
|
21841
|
+
var STATUS_VALUES = ["draft", "active", "deprecated"];
|
|
21842
|
+
var frontmatterSchema = external_exports.object({
|
|
21843
|
+
id: external_exports.string().regex(ID_REGEX, { message: "invalid id slug" }),
|
|
21844
|
+
feature: external_exports.string().min(1).refine((value) => value.trim().length > 0, { message: "feature cannot be blank" }),
|
|
21845
|
+
owner: external_exports.string().optional(),
|
|
21846
|
+
status: external_exports.enum(STATUS_VALUES).default("active"),
|
|
21847
|
+
tags: external_exports.array(external_exports.string()).default([]),
|
|
21848
|
+
requires: external_exports.array(external_exports.string()).default([]),
|
|
21849
|
+
links: external_exports.array(external_exports.string().regex(URL_PATTERN, { message: "must be a URL" })).default([]),
|
|
21850
|
+
scenarioId: external_exports.string().min(1).optional(),
|
|
21851
|
+
timeout: external_exports.number().int().positive().optional()
|
|
21852
|
+
});
|
|
21853
|
+
var safeParseYaml = (0, import_neverthrow5.fromThrowable)((text) => yaml.parse(text), (cause) => ({
|
|
21854
|
+
type: "MALFORMED_FRONTMATTER",
|
|
21766
21855
|
cause
|
|
21767
21856
|
}));
|
|
21768
21857
|
function normalizeRawInput(value) {
|
|
@@ -21771,49 +21860,45 @@ function normalizeRawInput(value) {
|
|
|
21771
21860
|
}
|
|
21772
21861
|
function splitFrontmatter(raw) {
|
|
21773
21862
|
if (!raw.startsWith(FRONTMATTER_OPEN)) {
|
|
21774
|
-
return (0,
|
|
21863
|
+
return (0, import_neverthrow5.err)({ type: "MALFORMED_FRONTMATTER", cause: "missing frontmatter delimiter" });
|
|
21775
21864
|
}
|
|
21776
21865
|
const afterOpen = raw.slice(FRONTMATTER_OPEN.length);
|
|
21777
21866
|
if (afterOpen.startsWith(FRONTMATTER_EMPTY_CLOSE)) {
|
|
21778
|
-
return (0,
|
|
21867
|
+
return (0, import_neverthrow5.ok)({
|
|
21779
21868
|
frontmatterRaw: "",
|
|
21780
21869
|
body: afterOpen.slice(FRONTMATTER_EMPTY_CLOSE.length)
|
|
21781
21870
|
});
|
|
21782
21871
|
}
|
|
21783
21872
|
const closeIndex = afterOpen.indexOf(FRONTMATTER_CLOSE);
|
|
21784
21873
|
if (closeIndex === -1) {
|
|
21785
|
-
return (0,
|
|
21874
|
+
return (0, import_neverthrow5.err)({ type: "MALFORMED_FRONTMATTER", cause: "missing frontmatter delimiter" });
|
|
21786
21875
|
}
|
|
21787
|
-
return (0,
|
|
21876
|
+
return (0, import_neverthrow5.ok)({
|
|
21788
21877
|
frontmatterRaw: afterOpen.slice(0, closeIndex),
|
|
21789
21878
|
body: afterOpen.slice(closeIndex + FRONTMATTER_CLOSE.length)
|
|
21790
21879
|
});
|
|
21791
21880
|
}
|
|
21792
21881
|
function normalizeFrontmatter(value) {
|
|
21793
21882
|
if (value === null || value === void 0) {
|
|
21794
|
-
return (0,
|
|
21883
|
+
return (0, import_neverthrow5.ok)({});
|
|
21795
21884
|
}
|
|
21796
21885
|
if (typeof value !== "object" || Array.isArray(value)) {
|
|
21797
|
-
return (0,
|
|
21886
|
+
return (0, import_neverthrow5.err)({ type: "MALFORMED_FRONTMATTER", cause: "frontmatter must be a mapping" });
|
|
21798
21887
|
}
|
|
21799
|
-
return (0,
|
|
21888
|
+
return (0, import_neverthrow5.ok)(value);
|
|
21800
21889
|
}
|
|
21801
21890
|
function parseFrontmatterYaml(yamlText) {
|
|
21802
21891
|
if (yamlText.trim() === "") {
|
|
21803
|
-
return (0,
|
|
21892
|
+
return (0, import_neverthrow5.ok)({});
|
|
21804
21893
|
}
|
|
21805
21894
|
return safeParseYaml(yamlText).andThen(normalizeFrontmatter);
|
|
21806
21895
|
}
|
|
21807
|
-
function
|
|
21808
|
-
const
|
|
21809
|
-
if (
|
|
21810
|
-
return (0,
|
|
21896
|
+
function validateFrontmatter(raw) {
|
|
21897
|
+
const parsed = frontmatterSchema.safeParse(raw);
|
|
21898
|
+
if (!parsed.success) {
|
|
21899
|
+
return (0, import_neverthrow5.err)({ type: "MALFORMED_FRONTMATTER", cause: parsed.error });
|
|
21811
21900
|
}
|
|
21812
|
-
return (0,
|
|
21813
|
-
}
|
|
21814
|
-
function extractOptionalNumber(fm, key) {
|
|
21815
|
-
const value = fm[key];
|
|
21816
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
21901
|
+
return (0, import_neverthrow5.ok)(parsed.data);
|
|
21817
21902
|
}
|
|
21818
21903
|
function findHeadingLine(lines, heading) {
|
|
21819
21904
|
return lines.findIndex((line) => line.trim() === heading);
|
|
@@ -21832,81 +21917,55 @@ function extractSection(body, heading) {
|
|
|
21832
21917
|
const endIndex = findNextHeadingIndex(lines, afterHeading);
|
|
21833
21918
|
return lines.slice(afterHeading, endIndex).join("\n").trim();
|
|
21834
21919
|
}
|
|
21920
|
+
function findCaseVariant(body, expected) {
|
|
21921
|
+
const expectedLower = expected.slice("## ".length).toLowerCase();
|
|
21922
|
+
const lines = body.split("\n");
|
|
21923
|
+
for (const line of lines) {
|
|
21924
|
+
const match = VARIANT_PATTERN.exec(line.trim());
|
|
21925
|
+
const heading = match?.[1];
|
|
21926
|
+
if (heading !== void 0 && heading !== expected.slice("## ".length) && heading.toLowerCase() === expectedLower) {
|
|
21927
|
+
return `## ${heading}`;
|
|
21928
|
+
}
|
|
21929
|
+
}
|
|
21930
|
+
return void 0;
|
|
21931
|
+
}
|
|
21835
21932
|
function extractSpecSections(body) {
|
|
21836
21933
|
const setup = extractSection(body, SETUP_HEADING);
|
|
21837
21934
|
if (setup === void 0) {
|
|
21838
|
-
|
|
21935
|
+
const suggestedHeading = findCaseVariant(body, SETUP_HEADING);
|
|
21936
|
+
return (0, import_neverthrow5.err)(suggestedHeading === void 0 ? { type: "MISSING_SETUP_SECTION" } : { type: "MISSING_SETUP_SECTION", suggestedHeading });
|
|
21839
21937
|
}
|
|
21840
21938
|
const stepsBody = extractSection(body, STEPS_HEADING);
|
|
21841
21939
|
if (stepsBody === void 0) {
|
|
21842
|
-
|
|
21843
|
-
|
|
21844
|
-
|
|
21845
|
-
}
|
|
21846
|
-
|
|
21847
|
-
|
|
21848
|
-
|
|
21849
|
-
|
|
21850
|
-
|
|
21851
|
-
|
|
21852
|
-
|
|
21853
|
-
|
|
21854
|
-
|
|
21855
|
-
|
|
21856
|
-
|
|
21857
|
-
|
|
21858
|
-
|
|
21859
|
-
const {
|
|
21860
|
-
|
|
21861
|
-
}
|
|
21862
|
-
function buildStepWithOutcome(intent, remainder) {
|
|
21863
|
-
const { text: outcome, hint } = splitHint(remainder);
|
|
21864
|
-
if (hint === void 0) {
|
|
21865
|
-
return { intent, outcome };
|
|
21866
|
-
}
|
|
21867
|
-
return { intent, outcome, hint };
|
|
21868
|
-
}
|
|
21869
|
-
function buildStep(body) {
|
|
21870
|
-
const arrowIndex = body.indexOf(ARROW_SEPARATOR);
|
|
21871
|
-
if (arrowIndex === -1) {
|
|
21872
|
-
return buildStepWithoutOutcome(body);
|
|
21873
|
-
}
|
|
21874
|
-
const intent = body.slice(0, arrowIndex).trim();
|
|
21875
|
-
const remainder = body.slice(arrowIndex + ARROW_SEPARATOR.length);
|
|
21876
|
-
return buildStepWithOutcome(intent, remainder);
|
|
21877
|
-
}
|
|
21878
|
-
function parseStepLine(line) {
|
|
21879
|
-
const match = STEP_LINE_PATTERN.exec(line.trim());
|
|
21880
|
-
return match === null ? void 0 : buildStep(match[1] ?? "");
|
|
21881
|
-
}
|
|
21882
|
-
function parseSteps(stepsBody) {
|
|
21883
|
-
const steps = stepsBody.split("\n").map((line) => parseStepLine(line)).filter((step) => step !== void 0);
|
|
21884
|
-
if (steps.length === 0) {
|
|
21885
|
-
return (0, import_neverthrow4.err)({ type: "STORED_SPEC_PARSE_FAILED", reason: "empty steps section" });
|
|
21886
|
-
}
|
|
21887
|
-
return (0, import_neverthrow4.ok)(steps);
|
|
21888
|
-
}
|
|
21889
|
-
function parseAssertions(body) {
|
|
21890
|
-
if (body === void 0 || body.trim() === "") {
|
|
21891
|
-
return void 0;
|
|
21892
|
-
}
|
|
21893
|
-
const items = body.split("\n").map((line) => line.trim()).filter((line) => line.startsWith(ASSERTION_BULLET)).map((line) => line.slice(ASSERTION_BULLET.length).trim());
|
|
21894
|
-
return items.length === 0 ? void 0 : items;
|
|
21895
|
-
}
|
|
21896
|
-
function buildSpec(input) {
|
|
21897
|
-
const base = { feature: input.feature, setup: input.setup, steps: input.steps };
|
|
21898
|
-
const withAssertions = input.assertions === void 0 ? base : { ...base, assertions: input.assertions };
|
|
21899
|
-
return input.timeoutMs === void 0 ? withAssertions : { ...withAssertions, timeoutMs: input.timeoutMs };
|
|
21940
|
+
const suggestedHeading = findCaseVariant(body, STEPS_HEADING);
|
|
21941
|
+
return (0, import_neverthrow5.err)(suggestedHeading === void 0 ? { type: "MISSING_STEPS_SECTION" } : { type: "MISSING_STEPS_SECTION", suggestedHeading });
|
|
21942
|
+
}
|
|
21943
|
+
return (0, import_neverthrow5.ok)({ setup, stepsBody, assertionsBody: extractSection(body, ASSERTIONS_HEADING) });
|
|
21944
|
+
}
|
|
21945
|
+
function buildSpec({ fm, setup, steps, assertions }) {
|
|
21946
|
+
const base = {
|
|
21947
|
+
id: fm.id,
|
|
21948
|
+
feature: fm.feature,
|
|
21949
|
+
status: fm.status,
|
|
21950
|
+
tags: fm.tags,
|
|
21951
|
+
requires: fm.requires,
|
|
21952
|
+
links: fm.links,
|
|
21953
|
+
setup,
|
|
21954
|
+
steps,
|
|
21955
|
+
assertions
|
|
21956
|
+
};
|
|
21957
|
+
const withOwner = fm.owner === void 0 ? base : { ...base, owner: fm.owner };
|
|
21958
|
+
const withScenarioId = fm.scenarioId === void 0 ? withOwner : { ...withOwner, scenarioId: fm.scenarioId };
|
|
21959
|
+
return fm.timeout === void 0 ? withScenarioId : { ...withScenarioId, timeoutSeconds: fm.timeout };
|
|
21900
21960
|
}
|
|
21901
21961
|
function parseSpecShared(raw) {
|
|
21902
21962
|
const normalized = normalizeRawInput(raw);
|
|
21903
|
-
return splitFrontmatter(normalized).andThen(({ frontmatterRaw, body }) => parseFrontmatterYaml(frontmatterRaw).andThen((frontmatter) =>
|
|
21963
|
+
return splitFrontmatter(normalized).andThen(({ frontmatterRaw, body }) => parseFrontmatterYaml(frontmatterRaw).andThen((frontmatter) => validateFrontmatter(frontmatter).andThen((fm) => extractSpecSections(body).andThen((sections) => parseSteps(sections.stepsBody).map((steps) => ({
|
|
21904
21964
|
spec: buildSpec({
|
|
21905
|
-
|
|
21965
|
+
fm,
|
|
21906
21966
|
setup: sections.setup,
|
|
21907
21967
|
steps,
|
|
21908
|
-
assertions: parseAssertions(sections.assertionsBody)
|
|
21909
|
-
timeoutMs: extractOptionalNumber(frontmatter, "timeout")
|
|
21968
|
+
assertions: parseAssertions(sections.assertionsBody)
|
|
21910
21969
|
}),
|
|
21911
21970
|
frontmatter
|
|
21912
21971
|
}))))));
|
|
@@ -21916,7 +21975,7 @@ function parseSpecShared(raw) {
|
|
|
21916
21975
|
var yaml2 = __toESM(require_dist(), 1);
|
|
21917
21976
|
|
|
21918
21977
|
// ../../packages/shared/dist/retry.js
|
|
21919
|
-
var
|
|
21978
|
+
var import_neverthrow6 = __toESM(require_index_cjs(), 1);
|
|
21920
21979
|
// Annotate the CommonJS export names for ESM import in node:
|
|
21921
21980
|
0 && (module.exports = {
|
|
21922
21981
|
CATALOG_INTERFACE_VERSION,
|
package/dist/consumer-api.d.ts
CHANGED
|
@@ -73,16 +73,26 @@ export type SuiteId = string & {
|
|
|
73
73
|
readonly __brand: "SuiteId";
|
|
74
74
|
};
|
|
75
75
|
export interface SpecStep {
|
|
76
|
+
readonly index: number;
|
|
76
77
|
readonly intent: string;
|
|
77
78
|
readonly outcome?: string;
|
|
78
79
|
readonly hint?: string;
|
|
80
|
+
readonly isOptional: boolean;
|
|
79
81
|
}
|
|
82
|
+
export type SpecStatus = "draft" | "active" | "deprecated";
|
|
80
83
|
export interface Spec {
|
|
84
|
+
readonly id: SpecId;
|
|
81
85
|
readonly feature: string;
|
|
86
|
+
readonly owner?: string;
|
|
87
|
+
readonly status: SpecStatus;
|
|
88
|
+
readonly tags: readonly string[];
|
|
89
|
+
readonly requires: readonly string[];
|
|
90
|
+
readonly links: readonly string[];
|
|
91
|
+
readonly scenarioId?: string;
|
|
92
|
+
readonly timeoutSeconds?: number;
|
|
82
93
|
readonly setup: string;
|
|
83
94
|
readonly steps: readonly SpecStep[];
|
|
84
|
-
readonly assertions
|
|
85
|
-
readonly timeoutMs?: number;
|
|
95
|
+
readonly assertions: readonly string[];
|
|
86
96
|
}
|
|
87
97
|
export interface CatalogSpec {
|
|
88
98
|
readonly id: SpecId;
|
|
@@ -118,14 +128,21 @@ export interface Catalog {
|
|
|
118
128
|
getSpecs(): ResultAsync<readonly CatalogSpec[], CatalogError>;
|
|
119
129
|
getSuites(): ResultAsync<readonly CatalogSuite[], CatalogError>;
|
|
120
130
|
}
|
|
121
|
-
export
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
131
|
+
export type SpecParseError = {
|
|
132
|
+
type: "MALFORMED_FRONTMATTER";
|
|
133
|
+
cause: unknown;
|
|
134
|
+
} | {
|
|
135
|
+
type: "MISSING_SETUP_SECTION";
|
|
136
|
+
suggestedHeading?: string;
|
|
137
|
+
} | {
|
|
138
|
+
type: "MISSING_STEPS_SECTION";
|
|
139
|
+
suggestedHeading?: string;
|
|
140
|
+
} | {
|
|
141
|
+
type: "EMPTY_STEPS_SECTION";
|
|
142
|
+
};
|
|
126
143
|
export declare function parseSpecShared(raw: string): Result<{
|
|
127
144
|
readonly spec: Spec;
|
|
128
145
|
readonly frontmatter: Record<string, unknown>;
|
|
129
|
-
},
|
|
146
|
+
}, SpecParseError>;
|
|
130
147
|
|
|
131
148
|
export {};
|