@autometa/runner 0.6.4 → 1.0.0-rc.1

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/index.cjs ADDED
@@ -0,0 +1,2212 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var executor = require('@autometa/executor');
6
+ var cucumberExpressions$1 = require('@autometa/cucumber-expressions');
7
+ var scopes = require('@autometa/scopes');
8
+ var cucumberExpressions = require('@cucumber/cucumber-expressions');
9
+ var assertions = require('@autometa/assertions');
10
+ var injection = require('@autometa/injection');
11
+ var coordinator = require('@autometa/coordinator');
12
+
13
+ var __accessCheck = (obj, member, msg) => {
14
+ if (!member.has(obj))
15
+ throw TypeError("Cannot " + msg);
16
+ };
17
+ var __privateGet = (obj, member, getter) => {
18
+ __accessCheck(obj, member, "read from private field");
19
+ return getter ? getter.call(obj) : member.get(obj);
20
+ };
21
+ var __privateAdd = (obj, member, value) => {
22
+ if (member.has(obj))
23
+ throw TypeError("Cannot add the same private member more than once");
24
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
25
+ };
26
+ var __privateSet = (obj, member, value, setter) => {
27
+ __accessCheck(obj, member, "write to private field");
28
+ setter ? setter.call(obj, value) : member.set(obj, value);
29
+ return value;
30
+ };
31
+ var _registry;
32
+ var ParameterRegistryAdapter = class {
33
+ constructor(options = {}) {
34
+ __privateAdd(this, _registry, void 0);
35
+ __privateSet(this, _registry, options.registry ?? new cucumberExpressions.ParameterTypeRegistry());
36
+ }
37
+ get registry() {
38
+ return __privateGet(this, _registry);
39
+ }
40
+ get parameterTypes() {
41
+ return __privateGet(this, _registry).parameterTypes;
42
+ }
43
+ lookupByTypeName(name) {
44
+ return __privateGet(this, _registry).lookupByTypeName(name);
45
+ }
46
+ lookupByRegexp(parameterTypeRegexp, expressionRegexp, text) {
47
+ return __privateGet(this, _registry).lookupByRegexp(parameterTypeRegexp, expressionRegexp, text);
48
+ }
49
+ defineParameterType(definition) {
50
+ const parameter = definition;
51
+ __privateGet(this, _registry).defineParameterType(parameter);
52
+ return parameter;
53
+ }
54
+ };
55
+ _registry = new WeakMap();
56
+ function createParameterRegistryAdapter(options) {
57
+ return new ParameterRegistryAdapter(options);
58
+ }
59
+
60
+ // src/core/runner-context.ts
61
+ var RunnerContext = class _RunnerContext {
62
+ constructor(options = {}) {
63
+ this.registryAdapter = options.parameterRegistry ? createParameterRegistryAdapter({ registry: options.parameterRegistry }) : createParameterRegistryAdapter();
64
+ this.defineParameterTypeFn = cucumberExpressions$1.createParameterTypes(
65
+ options.parameterTypesOptions
66
+ );
67
+ this.registerDefaultParameterTypesFn = cucumberExpressions$1.createDefaultParameterTypes(
68
+ options.parameterTypesOptions
69
+ );
70
+ const scopeOptions = _RunnerContext.extractScopeOptions(options);
71
+ this.scopesInternal = scopes.createScopes({
72
+ ...scopeOptions,
73
+ parameterRegistry: this.registryAdapter
74
+ });
75
+ if (options.registerDefaultParameterTypes !== false) {
76
+ this.registerDefaultParameterTypes();
77
+ }
78
+ if (options.parameterTypes && options.parameterTypes.length > 0) {
79
+ this.defineParameterTypes(...options.parameterTypes);
80
+ }
81
+ }
82
+ get scopes() {
83
+ return this.scopesInternal;
84
+ }
85
+ get parameterRegistry() {
86
+ return this.registryAdapter.registry;
87
+ }
88
+ get parameterRegistryAdapter() {
89
+ return this.registryAdapter;
90
+ }
91
+ get plan() {
92
+ return this.scopesInternal.plan();
93
+ }
94
+ defineParameterType(definition) {
95
+ return this.defineParameterTypeFn(this.parameterRegistry, definition);
96
+ }
97
+ defineParameterTypes(...definitions) {
98
+ this.defineParameterTypeFn.many(this.parameterRegistry, ...definitions);
99
+ return this.parameterRegistry;
100
+ }
101
+ registerDefaultParameterTypes() {
102
+ return this.registerDefaultParameterTypesFn(this.parameterRegistry);
103
+ }
104
+ lookupParameterType(name) {
105
+ return this.parameterRegistry.lookupByTypeName(name);
106
+ }
107
+ static extractScopeOptions(options) {
108
+ const {
109
+ parameterRegistry: _parameterRegistry,
110
+ parameterTypes: _parameterTypes,
111
+ parameterTypesOptions: _parameterTypesOptions,
112
+ registerDefaultParameterTypes: _registerDefaultParameterTypes,
113
+ ...scopeOptions
114
+ } = options;
115
+ return scopeOptions;
116
+ }
117
+ };
118
+
119
+ // src/dsl/create-runner.ts
120
+ var hookWrapperCache = /* @__PURE__ */ new WeakMap();
121
+ function wrapHook(hook) {
122
+ if (typeof hook !== "function") {
123
+ throw new TypeError("Hook DSL must be a function");
124
+ }
125
+ const cached = hookWrapperCache.get(hook);
126
+ if (cached) {
127
+ return cached;
128
+ }
129
+ const callable = (first, second, third) => {
130
+ if (typeof first === "string") {
131
+ return hook(first, second, third);
132
+ }
133
+ return hook(first, second);
134
+ };
135
+ hookWrapperCache.set(hook, callable);
136
+ const assignVariant = (variant, source) => {
137
+ if (typeof source === "function") {
138
+ callable[variant] = wrapHook(
139
+ source
140
+ );
141
+ }
142
+ };
143
+ assignVariant("skip", hook.skip);
144
+ assignVariant("only", hook.only);
145
+ assignVariant("failing", hook.failing);
146
+ assignVariant("concurrent", hook.concurrent);
147
+ return callable;
148
+ }
149
+ function wrapStepHandler(handler) {
150
+ return (world, ...args) => {
151
+ const runtime = executor.createStepRuntime(world);
152
+ const withRuntime = handler;
153
+ const withoutRuntime = handler;
154
+ const paramLength = typeof handler === "function" ? handler.length : 0;
155
+ const expectsRuntime = paramLength > args.length + 1;
156
+ const invocationArgs = expectsRuntime ? [...args, runtime, world] : [...args, world];
157
+ const callable = expectsRuntime ? withRuntime : withoutRuntime;
158
+ return Reflect.apply(callable, world, invocationArgs);
159
+ };
160
+ }
161
+ function enhanceStepDsl(dsl) {
162
+ const cache = /* @__PURE__ */ new Map();
163
+ const convert = (source) => {
164
+ const existing = cache.get(source);
165
+ if (existing) {
166
+ return existing;
167
+ }
168
+ const invoke = (expression, handler, options) => source(
169
+ expression,
170
+ wrapStepHandler(handler),
171
+ options
172
+ );
173
+ cache.set(source, invoke);
174
+ invoke.skip = convert(source.skip);
175
+ invoke.only = convert(source.only);
176
+ invoke.failing = convert(source.failing);
177
+ invoke.concurrent = convert(source.concurrent);
178
+ invoke.tags = (...inputs) => convert(source.tags(...inputs));
179
+ return invoke;
180
+ };
181
+ return convert(dsl);
182
+ }
183
+ function createRunner(options = {}) {
184
+ const context = new RunnerContext(options);
185
+ const scopes = context.scopes;
186
+ const given = enhanceStepDsl(scopes.given);
187
+ const when = enhanceStepDsl(scopes.when);
188
+ const then = enhanceStepDsl(scopes.then);
189
+ const and = enhanceStepDsl(scopes.and);
190
+ const but = enhanceStepDsl(scopes.but);
191
+ const defineParameterTypesFromList = (definitions) => context.defineParameterTypes(...definitions);
192
+ const beforeFeatureHook = wrapHook(scopes.beforeFeature);
193
+ const afterFeatureHook = wrapHook(scopes.afterFeature);
194
+ const beforeRuleHook = wrapHook(scopes.beforeRule);
195
+ const afterRuleHook = wrapHook(scopes.afterRule);
196
+ const beforeScenarioHook = wrapHook(scopes.beforeScenario);
197
+ const afterScenarioHook = wrapHook(scopes.afterScenario);
198
+ const beforeScenarioOutlineHook = wrapHook(scopes.beforeScenarioOutline);
199
+ const afterScenarioOutlineHook = wrapHook(scopes.afterScenarioOutline);
200
+ const beforeStepHook = wrapHook(scopes.beforeStep);
201
+ const afterStepHook = wrapHook(scopes.afterStep);
202
+ const environment = {
203
+ context,
204
+ parameterRegistry: context.parameterRegistry,
205
+ getPlan: () => context.plan,
206
+ defineParameterType: (definition) => context.defineParameterType(definition),
207
+ defineParameterTypes: (...definitions) => context.defineParameterTypes(...definitions),
208
+ defineParameterTypesFromList,
209
+ registerDefaultParameterTypes: () => context.registerDefaultParameterTypes(),
210
+ lookupParameterType: (name) => context.lookupParameterType(name),
211
+ feature: scopes.feature,
212
+ rule: scopes.rule,
213
+ scenario: scopes.scenario,
214
+ scenarioOutline: scopes.scenarioOutline,
215
+ given,
216
+ when,
217
+ then,
218
+ and,
219
+ but,
220
+ beforeFeature: beforeFeatureHook,
221
+ afterFeature: afterFeatureHook,
222
+ beforeRule: beforeRuleHook,
223
+ afterRule: afterRuleHook,
224
+ beforeScenario: beforeScenarioHook,
225
+ afterScenario: afterScenarioHook,
226
+ beforeScenarioOutline: beforeScenarioOutlineHook,
227
+ afterScenarioOutline: afterScenarioOutlineHook,
228
+ beforeStep: beforeStepHook,
229
+ afterStep: afterStepHook,
230
+ Given: given,
231
+ When: when,
232
+ Then: then,
233
+ And: and,
234
+ But: but,
235
+ plan: scopes.plan,
236
+ BeforeFeature: beforeFeatureHook,
237
+ AfterFeature: afterFeatureHook,
238
+ BeforeRule: beforeRuleHook,
239
+ AfterRule: afterRuleHook,
240
+ BeforeScenario: beforeScenarioHook,
241
+ AfterScenario: afterScenarioHook,
242
+ BeforeScenarioOutline: beforeScenarioOutlineHook,
243
+ AfterScenarioOutline: afterScenarioOutlineHook,
244
+ BeforeStep: beforeStepHook,
245
+ AfterStep: afterStepHook
246
+ };
247
+ return environment;
248
+ }
249
+
250
+ // src/dsl/create-global-runner.ts
251
+ function createGlobalRunner(initialOptions) {
252
+ let lastOptions = initialOptions;
253
+ function instantiate(options) {
254
+ if (options) {
255
+ lastOptions = options;
256
+ return createRunner(options);
257
+ }
258
+ if (lastOptions) {
259
+ return createRunner(lastOptions);
260
+ }
261
+ return createRunner();
262
+ }
263
+ let current = instantiate(initialOptions);
264
+ const target = {
265
+ reset(options) {
266
+ current = instantiate(options);
267
+ return current;
268
+ },
269
+ useEnvironment(environment) {
270
+ current = environment;
271
+ return current;
272
+ },
273
+ getEnvironment() {
274
+ return current;
275
+ }
276
+ };
277
+ const forwardedKeys = /* @__PURE__ */ new Set([
278
+ "reset",
279
+ "useEnvironment",
280
+ "getEnvironment"
281
+ ]);
282
+ return new Proxy(target, {
283
+ get(obj, prop, receiver) {
284
+ if (forwardedKeys.has(prop)) {
285
+ return Reflect.get(obj, prop, receiver);
286
+ }
287
+ const value = current[prop];
288
+ if (typeof value === "function") {
289
+ return value.bind(current);
290
+ }
291
+ return value;
292
+ },
293
+ has(_, prop) {
294
+ if (forwardedKeys.has(prop)) {
295
+ return true;
296
+ }
297
+ return prop in current;
298
+ },
299
+ ownKeys() {
300
+ const forwardable = Array.from(forwardedKeys).filter(
301
+ (key) => typeof key === "string" || typeof key === "symbol"
302
+ );
303
+ const keys = /* @__PURE__ */ new Set([
304
+ ...Reflect.ownKeys(current),
305
+ ...forwardable
306
+ ]);
307
+ return Array.from(keys);
308
+ },
309
+ getOwnPropertyDescriptor(obj, prop) {
310
+ if (forwardedKeys.has(prop)) {
311
+ return {
312
+ configurable: true,
313
+ enumerable: false,
314
+ value: Reflect.get(obj, prop)
315
+ };
316
+ }
317
+ return Object.getOwnPropertyDescriptor(current, prop);
318
+ }
319
+ });
320
+ }
321
+ function createDecoratorRunner(options = {}) {
322
+ const context = new RunnerContext(options);
323
+ const registry = new scopes.DecoratorScopeRegistry();
324
+ const scopeOptions = RunnerContext.extractScopeOptions(options);
325
+ return {
326
+ feature(token, descriptor) {
327
+ registry.registerFeature(token, descriptor);
328
+ },
329
+ rule(featureToken, token, descriptor) {
330
+ registry.registerRule(featureToken, token, descriptor);
331
+ },
332
+ scenario(token, descriptor, scenarioContext) {
333
+ registry.registerScenario(token, descriptor, scenarioContext);
334
+ },
335
+ step(scenarioToken, keyword, expression, handler, options2) {
336
+ registry.registerStep(scenarioToken, {
337
+ keyword,
338
+ expression,
339
+ handler,
340
+ ...options2 ? { options: options2 } : {}
341
+ });
342
+ },
343
+ hook(scopeToken, type, handler, description, options2) {
344
+ registry.registerHook(scopeToken, {
345
+ type,
346
+ handler,
347
+ ...description ? { description } : {},
348
+ ...options2 ? { options: options2 } : {}
349
+ });
350
+ },
351
+ context,
352
+ buildPlan() {
353
+ return registry.build(
354
+ createScopeOptions(scopeOptions, context.parameterRegistryAdapter)
355
+ );
356
+ }
357
+ };
358
+ }
359
+ function createScopeOptions(opts, parameterRegistry) {
360
+ return {
361
+ ...opts,
362
+ parameterRegistry
363
+ };
364
+ }
365
+
366
+ // src/decorators/create-runner-decorators.ts
367
+ function createRunnerDecorators(environment) {
368
+ const stepMetadata = /* @__PURE__ */ new WeakMap();
369
+ const hookMetadata = /* @__PURE__ */ new WeakMap();
370
+ const scenarioRecords = /* @__PURE__ */ new WeakMap();
371
+ const pendingScenarioData = /* @__PURE__ */ new WeakMap();
372
+ const ruleRecords = /* @__PURE__ */ new WeakMap();
373
+ const pendingRuleData = /* @__PURE__ */ new WeakMap();
374
+ const featureHooks = /* @__PURE__ */ new WeakMap();
375
+ function getOrCreateRecordMap(constructor) {
376
+ let records = scenarioRecords.get(constructor);
377
+ if (!records) {
378
+ records = /* @__PURE__ */ new Map();
379
+ scenarioRecords.set(constructor, records);
380
+ }
381
+ return records;
382
+ }
383
+ function getOrCreatePending(constructor) {
384
+ let pending = pendingScenarioData.get(constructor);
385
+ if (!pending) {
386
+ pending = /* @__PURE__ */ new Map();
387
+ pendingScenarioData.set(constructor, pending);
388
+ }
389
+ return pending;
390
+ }
391
+ function getOrCreateRuleRecordMap(constructor) {
392
+ let records = ruleRecords.get(constructor);
393
+ if (!records) {
394
+ records = /* @__PURE__ */ new Map();
395
+ ruleRecords.set(constructor, records);
396
+ }
397
+ return records;
398
+ }
399
+ function getOrCreateRulePending(constructor) {
400
+ let pending = pendingRuleData.get(constructor);
401
+ if (!pending) {
402
+ pending = /* @__PURE__ */ new Map();
403
+ pendingRuleData.set(constructor, pending);
404
+ }
405
+ return pending;
406
+ }
407
+ function addStepAssociation(constructor, scenarioKey, stepKey) {
408
+ const records = scenarioRecords.get(constructor);
409
+ const record = records?.get(scenarioKey);
410
+ if (record) {
411
+ record.steps.add(stepKey);
412
+ return;
413
+ }
414
+ const pending = getOrCreatePending(constructor);
415
+ let entry = pending.get(scenarioKey);
416
+ if (!entry) {
417
+ entry = { steps: /* @__PURE__ */ new Set(), hooks: [] };
418
+ pending.set(scenarioKey, entry);
419
+ }
420
+ entry.steps.add(stepKey);
421
+ }
422
+ function addHookAssociation(constructor, scenarioKey, hook) {
423
+ const records = scenarioRecords.get(constructor);
424
+ const record = records?.get(scenarioKey);
425
+ if (record) {
426
+ record.hooks.push(hook);
427
+ return;
428
+ }
429
+ const pending = getOrCreatePending(constructor);
430
+ let entry = pending.get(scenarioKey);
431
+ if (!entry) {
432
+ entry = { steps: /* @__PURE__ */ new Set(), hooks: [] };
433
+ pending.set(scenarioKey, entry);
434
+ }
435
+ entry.hooks.push(hook);
436
+ }
437
+ function addRuleScenarioAssociation(constructor, ruleKey, scenarioKey) {
438
+ const records = ruleRecords.get(constructor);
439
+ const record = records?.get(ruleKey);
440
+ if (record) {
441
+ record.scenarios.add(scenarioKey);
442
+ return record.token;
443
+ }
444
+ const pending = getOrCreateRulePending(constructor);
445
+ let entry = pending.get(ruleKey);
446
+ if (!entry) {
447
+ entry = { scenarios: /* @__PURE__ */ new Set(), hooks: [] };
448
+ pending.set(ruleKey, entry);
449
+ }
450
+ entry.scenarios.add(scenarioKey);
451
+ return void 0;
452
+ }
453
+ function addRuleHookAssociation(constructor, ruleKey, hook) {
454
+ const records = ruleRecords.get(constructor);
455
+ const record = records?.get(ruleKey);
456
+ if (record) {
457
+ record.hooks.push(hook);
458
+ return;
459
+ }
460
+ const pending = getOrCreateRulePending(constructor);
461
+ let entry = pending.get(ruleKey);
462
+ if (!entry) {
463
+ entry = { scenarios: /* @__PURE__ */ new Set(), hooks: [] };
464
+ pending.set(ruleKey, entry);
465
+ }
466
+ entry.hooks.push(hook);
467
+ }
468
+ function recordFeatureHook(constructor, hook) {
469
+ const hooks = featureHooks.get(constructor);
470
+ if (hooks) {
471
+ hooks.push(hook);
472
+ return;
473
+ }
474
+ featureHooks.set(constructor, [hook]);
475
+ }
476
+ function recordStepMetadata(target, propertyKey, metadata) {
477
+ let map = stepMetadata.get(target);
478
+ if (!map) {
479
+ map = /* @__PURE__ */ new Map();
480
+ stepMetadata.set(target, map);
481
+ }
482
+ map.set(propertyKey, metadata);
483
+ }
484
+ function recordHookMetadata(target, propertyKey, metadata) {
485
+ let map = hookMetadata.get(target);
486
+ if (!map) {
487
+ map = /* @__PURE__ */ new Map();
488
+ hookMetadata.set(target, map);
489
+ }
490
+ map.set(propertyKey, metadata);
491
+ }
492
+ function getStepMetadata(target, propertyKey) {
493
+ return stepMetadata.get(target)?.get(propertyKey);
494
+ }
495
+ function getHookMetadata(target, propertyKey) {
496
+ return hookMetadata.get(target)?.get(propertyKey);
497
+ }
498
+ function normalizeSteps(value) {
499
+ return value ? new Set(value) : /* @__PURE__ */ new Set();
500
+ }
501
+ function isReadonlyArray(value) {
502
+ return Array.isArray(value);
503
+ }
504
+ function toArray(input) {
505
+ return isReadonlyArray(input) ? input : [input];
506
+ }
507
+ function buildStepOptions(options) {
508
+ const candidate = {};
509
+ if (options.tags) {
510
+ candidate.tags = [...options.tags];
511
+ }
512
+ if (options.timeout !== void 0) {
513
+ candidate.timeout = options.timeout;
514
+ }
515
+ if (options.mode) {
516
+ candidate.mode = options.mode;
517
+ }
518
+ if (options.data) {
519
+ candidate.data = { ...options.data };
520
+ }
521
+ return Object.keys(candidate).length > 0 ? candidate : void 0;
522
+ }
523
+ function buildHookOptions(options) {
524
+ const candidate = {};
525
+ if (options.tags) {
526
+ candidate.tags = [...options.tags];
527
+ }
528
+ if (options.timeout !== void 0) {
529
+ candidate.timeout = options.timeout;
530
+ }
531
+ if (options.order !== void 0) {
532
+ candidate.order = options.order;
533
+ }
534
+ if (options.mode) {
535
+ candidate.mode = options.mode;
536
+ }
537
+ if (options.data) {
538
+ candidate.data = { ...options.data };
539
+ }
540
+ return Object.keys(candidate).length > 0 ? candidate : void 0;
541
+ }
542
+ function normalizeTagInputs(inputs) {
543
+ if (inputs.length === 0) {
544
+ return [];
545
+ }
546
+ const tags = [];
547
+ for (const input of inputs) {
548
+ if (typeof input === "string") {
549
+ if (input.length > 0) {
550
+ tags.push(input);
551
+ }
552
+ continue;
553
+ }
554
+ if (Array.isArray(input)) {
555
+ for (const tag of input) {
556
+ if (typeof tag === "string" && tag.length > 0) {
557
+ tags.push(tag);
558
+ }
559
+ }
560
+ }
561
+ }
562
+ return tags.length > 0 ? Array.from(new Set(tags)) : [];
563
+ }
564
+ function mergeStepOptions(base, extras) {
565
+ if (!base && !extras) {
566
+ return void 0;
567
+ }
568
+ const mergedTags = [
569
+ ...base?.tags ?? [],
570
+ ...extras?.tags ?? []
571
+ ];
572
+ const timeout = extras?.timeout ?? base?.timeout;
573
+ const mode = extras?.mode ?? base?.mode;
574
+ const data = {
575
+ ...base?.data ?? {},
576
+ ...extras?.data ?? {}
577
+ };
578
+ const tagsResult = mergedTags.length > 0 ? Array.from(new Set(mergedTags)) : void 0;
579
+ const hasData = Object.keys(data).length > 0;
580
+ if (!tagsResult && timeout === void 0 && mode === void 0 && !hasData) {
581
+ return void 0;
582
+ }
583
+ return {
584
+ ...tagsResult ? { tags: tagsResult } : {},
585
+ ...timeout !== void 0 ? { timeout } : {},
586
+ ...mode !== void 0 ? { mode } : {},
587
+ ...hasData ? { data } : {}
588
+ };
589
+ }
590
+ function applyExecutionModeToStepOptions(mode, options) {
591
+ if (!options) {
592
+ return mode === "default" ? void 0 : { mode };
593
+ }
594
+ return mode !== "default" ? { ...options, mode } : { ...options };
595
+ }
596
+ function clonePendingOption(pending) {
597
+ if (typeof pending === "boolean" || typeof pending === "string") {
598
+ return pending;
599
+ }
600
+ const reason = pending.reason;
601
+ return reason !== void 0 ? { reason } : {};
602
+ }
603
+ function cloneScopeOptions(options) {
604
+ const {
605
+ tags,
606
+ description,
607
+ timeout,
608
+ mode,
609
+ source,
610
+ data,
611
+ examples,
612
+ pending
613
+ } = options;
614
+ const cloned = {
615
+ ...tags ? { tags: [...tags] } : {},
616
+ ...description !== void 0 ? { description } : {},
617
+ ...timeout !== void 0 ? {
618
+ timeout: typeof timeout === "number" ? timeout : { ...timeout }
619
+ } : {},
620
+ ...mode !== void 0 ? { mode } : {},
621
+ ...source ? { source: { ...source } } : {},
622
+ ...data ? { data: { ...data } } : {},
623
+ ...examples ? {
624
+ examples: examples.map((example) => ({
625
+ ...example,
626
+ ...example.tags ? { tags: [...example.tags] } : {},
627
+ table: example.table.map((row) => [...row])
628
+ }))
629
+ } : {}
630
+ };
631
+ if (pending !== void 0) {
632
+ cloned.pending = clonePendingOption(pending);
633
+ }
634
+ return cloned;
635
+ }
636
+ function Feature(options = {}) {
637
+ return (target) => {
638
+ const constructor = target;
639
+ const descriptor = {
640
+ name: options.name ?? constructor.name ?? "Feature",
641
+ ...cloneScopeOptions(options)
642
+ };
643
+ environment.feature(constructor, descriptor);
644
+ const featureHookRefs = featureHooks.get(constructor);
645
+ if (featureHookRefs) {
646
+ for (const hook of featureHookRefs) {
647
+ const metadata = getHookMetadata(constructor.prototype, hook.propertyKey) ?? getHookMetadata(constructor, hook.propertyKey);
648
+ if (!metadata) {
649
+ throw new Error(
650
+ `Hook metadata missing for ${String(hook.propertyKey)} on feature ${descriptor.name}`
651
+ );
652
+ }
653
+ environment.hook(
654
+ constructor,
655
+ hook.type,
656
+ metadata.handler,
657
+ hook.description,
658
+ hook.options ?? metadata.options
659
+ );
660
+ }
661
+ featureHooks.delete(constructor);
662
+ }
663
+ const rules = ruleRecords.get(constructor);
664
+ if (rules) {
665
+ for (const [ruleKey, ruleRecord] of rules.entries()) {
666
+ environment.rule(constructor, ruleRecord.token, ruleRecord.descriptor);
667
+ const hooks = ruleRecord.hooks;
668
+ for (const hook of hooks) {
669
+ const metadata = getHookMetadata(constructor.prototype, hook.propertyKey) ?? getHookMetadata(constructor, hook.propertyKey);
670
+ if (!metadata) {
671
+ throw new Error(
672
+ `Hook metadata missing for ${String(hook.propertyKey)} on rule ${String(ruleKey)} of feature ${descriptor.name}`
673
+ );
674
+ }
675
+ environment.hook(
676
+ ruleRecord.token,
677
+ hook.type,
678
+ metadata.handler,
679
+ hook.description,
680
+ hook.options ?? metadata.options
681
+ );
682
+ }
683
+ }
684
+ }
685
+ const records = scenarioRecords.get(constructor);
686
+ if (records) {
687
+ for (const [scenarioKey, record] of records.entries()) {
688
+ if (record.ruleKey) {
689
+ const ruleRecord = rules?.get(record.ruleKey);
690
+ if (!ruleRecord) {
691
+ throw new Error(
692
+ `Scenario ${record.descriptor.name} references unknown rule ${String(record.ruleKey)}`
693
+ );
694
+ }
695
+ record.ruleToken = record.ruleToken ?? ruleRecord.token;
696
+ ruleRecord.scenarios.add(scenarioKey);
697
+ }
698
+ environment.scenario(record.token, record.descriptor, {
699
+ feature: constructor,
700
+ ...record.ruleToken ? { rule: record.ruleToken } : {}
701
+ });
702
+ for (const stepKey of record.steps) {
703
+ const metadata = getStepMetadata(constructor.prototype, stepKey) ?? getStepMetadata(constructor, stepKey);
704
+ if (!metadata) {
705
+ throw new Error(
706
+ `Step metadata missing for ${String(stepKey)} on feature ${descriptor.name}`
707
+ );
708
+ }
709
+ environment.step(
710
+ record.token,
711
+ metadata.keyword,
712
+ metadata.expression,
713
+ metadata.handler,
714
+ metadata.options
715
+ );
716
+ }
717
+ for (const hook of record.hooks) {
718
+ const metadata = getHookMetadata(constructor.prototype, hook.propertyKey) ?? getHookMetadata(constructor, hook.propertyKey);
719
+ if (!metadata) {
720
+ throw new Error(
721
+ `Hook metadata missing for ${String(hook.propertyKey)} on feature ${descriptor.name}`
722
+ );
723
+ }
724
+ environment.hook(
725
+ record.token,
726
+ hook.type,
727
+ metadata.handler,
728
+ hook.description,
729
+ hook.options ?? metadata.options
730
+ );
731
+ }
732
+ }
733
+ scenarioRecords.delete(constructor);
734
+ }
735
+ ruleRecords.delete(constructor);
736
+ pendingRuleData.delete(constructor);
737
+ pendingScenarioData.delete(constructor);
738
+ };
739
+ }
740
+ function Rule(options) {
741
+ return (target, propertyKey) => {
742
+ const constructor = resolveConstructor(target);
743
+ const descriptor = {
744
+ name: options.name,
745
+ ...cloneScopeOptions(options)
746
+ };
747
+ const records = getOrCreateRuleRecordMap(constructor);
748
+ if (records.has(propertyKey)) {
749
+ throw new Error(`Rule ${String(propertyKey)} already registered on feature ${constructor.name}`);
750
+ }
751
+ const token = Symbol(`rule:${String(propertyKey)}`);
752
+ const record = {
753
+ token,
754
+ descriptor,
755
+ hooks: [],
756
+ scenarios: /* @__PURE__ */ new Set()
757
+ };
758
+ const pending = pendingRuleData.get(constructor)?.get(propertyKey);
759
+ if (pending) {
760
+ for (const scenarioKey of pending.scenarios) {
761
+ record.scenarios.add(scenarioKey);
762
+ }
763
+ record.hooks.push(...pending.hooks);
764
+ pendingRuleData.get(constructor)?.delete(propertyKey);
765
+ }
766
+ records.set(propertyKey, record);
767
+ const scenarios = scenarioRecords.get(constructor);
768
+ if (scenarios) {
769
+ for (const scenarioKey of record.scenarios) {
770
+ const scenarioRecord = scenarios.get(scenarioKey);
771
+ if (scenarioRecord) {
772
+ scenarioRecord.ruleToken = token;
773
+ }
774
+ }
775
+ }
776
+ };
777
+ }
778
+ function Scenario(options) {
779
+ return (target, propertyKey) => {
780
+ const constructor = resolveConstructor(target);
781
+ const records = getOrCreateRecordMap(constructor);
782
+ const descriptor = {
783
+ name: options.name,
784
+ kind: options.kind ?? "scenario",
785
+ ...cloneScopeOptions(options)
786
+ };
787
+ const token = Symbol(`scenario:${String(propertyKey)}`);
788
+ const steps = normalizeSteps(options.steps);
789
+ const hooks = [];
790
+ const ruleKey = options.rule;
791
+ let ruleToken;
792
+ if (ruleKey !== void 0) {
793
+ ruleToken = addRuleScenarioAssociation(constructor, ruleKey, propertyKey);
794
+ }
795
+ const pending = pendingScenarioData.get(constructor)?.get(propertyKey);
796
+ if (pending) {
797
+ for (const stepKey of pending.steps) {
798
+ steps.add(stepKey);
799
+ }
800
+ hooks.push(...pending.hooks);
801
+ pendingScenarioData.get(constructor)?.delete(propertyKey);
802
+ }
803
+ const record = {
804
+ token,
805
+ descriptor,
806
+ steps,
807
+ hooks,
808
+ ...ruleKey !== void 0 ? { ruleKey } : {},
809
+ ...ruleToken ? { ruleToken } : {}
810
+ };
811
+ records.set(propertyKey, record);
812
+ };
813
+ }
814
+ function createStepDecorator(keyword) {
815
+ const factoryCache = /* @__PURE__ */ new Map();
816
+ const getCachedFactory = (mode, inheritedOptions) => {
817
+ const cacheForOptions = factoryCache.get(inheritedOptions);
818
+ return cacheForOptions?.get(mode);
819
+ };
820
+ const storeFactory = (mode, inheritedOptions, factory) => {
821
+ let cacheForOptions = factoryCache.get(inheritedOptions);
822
+ if (!cacheForOptions) {
823
+ cacheForOptions = /* @__PURE__ */ new Map();
824
+ factoryCache.set(inheritedOptions, cacheForOptions);
825
+ }
826
+ cacheForOptions.set(mode, factory);
827
+ };
828
+ const buildFactory = (mode, inheritedOptions) => {
829
+ const cached = getCachedFactory(mode, inheritedOptions);
830
+ if (cached) {
831
+ return cached;
832
+ }
833
+ const decorator = (expression, options) => {
834
+ if (!options || !options.scenario) {
835
+ throw new Error("Step decorator requires a scenario property key");
836
+ }
837
+ const scenarioRefs = toArray(options.scenario);
838
+ const explicitOptions = buildStepOptions(options);
839
+ const baseWithMode = mergeStepOptions(
840
+ inheritedOptions,
841
+ applyExecutionModeToStepOptions(mode)
842
+ );
843
+ const mergedOptions = mergeStepOptions(baseWithMode, explicitOptions);
844
+ const finalOptions = applyExecutionModeToStepOptions(mode, mergedOptions);
845
+ return (target, propertyKey, descriptor) => {
846
+ const handler = descriptor?.value;
847
+ if (typeof handler !== "function") {
848
+ throw new Error(
849
+ `Step decorator can only be applied to methods. ${String(propertyKey)} is not a function.`
850
+ );
851
+ }
852
+ recordStepMetadata(target, propertyKey, {
853
+ keyword,
854
+ expression,
855
+ handler,
856
+ ...finalOptions ? { options: finalOptions } : {}
857
+ });
858
+ const constructor = resolveConstructor(target);
859
+ for (const scenarioKey of scenarioRefs) {
860
+ addStepAssociation(constructor, scenarioKey, propertyKey);
861
+ }
862
+ };
863
+ };
864
+ storeFactory(mode, inheritedOptions, decorator);
865
+ decorator.tags = (...inputs) => {
866
+ const normalizedTags = normalizeTagInputs(inputs);
867
+ if (normalizedTags.length === 0) {
868
+ return decorator;
869
+ }
870
+ const tagOptions = {
871
+ tags: normalizedTags
872
+ };
873
+ const merged = mergeStepOptions(inheritedOptions, tagOptions);
874
+ return buildFactory(mode, merged);
875
+ };
876
+ decorator.skip = mode === "skip" ? decorator : buildFactory("skip", inheritedOptions);
877
+ decorator.only = mode === "only" ? decorator : buildFactory("only", inheritedOptions);
878
+ decorator.failing = mode === "failing" ? decorator : buildFactory("failing", inheritedOptions);
879
+ decorator.concurrent = mode === "concurrent" ? decorator : buildFactory("concurrent", inheritedOptions);
880
+ return decorator;
881
+ };
882
+ return buildFactory("default");
883
+ }
884
+ function createScenarioHookDecorator(type) {
885
+ return (options) => {
886
+ if (!options || !options.scenario) {
887
+ throw new Error("Hook decorator requires a scenario property key");
888
+ }
889
+ const scenarioRefs = toArray(options.scenario);
890
+ const hookOptions = buildHookOptions(options);
891
+ const description = options.description;
892
+ return (target, propertyKey, descriptor) => {
893
+ const handler = descriptor?.value;
894
+ if (typeof handler !== "function") {
895
+ throw new Error(
896
+ `Hook decorator can only be applied to methods. ${String(propertyKey)} is not a function.`
897
+ );
898
+ }
899
+ recordHookMetadata(target, propertyKey, {
900
+ handler,
901
+ ...hookOptions ? { options: hookOptions } : {}
902
+ });
903
+ const constructor = resolveConstructor(target);
904
+ const hookRef = {
905
+ propertyKey,
906
+ type,
907
+ ...description ? { description } : {},
908
+ ...hookOptions ? { options: hookOptions } : {}
909
+ };
910
+ for (const scenarioKey of scenarioRefs) {
911
+ addHookAssociation(constructor, scenarioKey, hookRef);
912
+ }
913
+ };
914
+ };
915
+ }
916
+ function createRuleHookDecorator(type) {
917
+ return (options) => {
918
+ if (!options || !options.rule) {
919
+ throw new Error("Rule hook decorator requires a rule property key");
920
+ }
921
+ const ruleRefs = toArray(options.rule);
922
+ const hookOptions = buildHookOptions(options);
923
+ const description = options.description;
924
+ return (target, propertyKey, descriptor) => {
925
+ const handler = descriptor?.value;
926
+ if (typeof handler !== "function") {
927
+ throw new Error(
928
+ `Hook decorator can only be applied to methods. ${String(propertyKey)} is not a function.`
929
+ );
930
+ }
931
+ recordHookMetadata(target, propertyKey, {
932
+ handler,
933
+ ...hookOptions ? { options: hookOptions } : {}
934
+ });
935
+ const constructor = resolveConstructor(target);
936
+ const hookRef = {
937
+ propertyKey,
938
+ type,
939
+ ...description ? { description } : {},
940
+ ...hookOptions ? { options: hookOptions } : {}
941
+ };
942
+ for (const ruleKey of ruleRefs) {
943
+ addRuleHookAssociation(constructor, ruleKey, hookRef);
944
+ }
945
+ };
946
+ };
947
+ }
948
+ function createFeatureHookDecorator(type) {
949
+ return (options = {}) => {
950
+ const hookOptions = buildHookOptions(options);
951
+ const description = options.description;
952
+ return (target, propertyKey, descriptor) => {
953
+ const handler = descriptor?.value;
954
+ if (typeof handler !== "function") {
955
+ throw new Error(
956
+ `Hook decorator can only be applied to methods. ${String(propertyKey)} is not a function.`
957
+ );
958
+ }
959
+ recordHookMetadata(target, propertyKey, {
960
+ handler,
961
+ ...hookOptions ? { options: hookOptions } : {}
962
+ });
963
+ const constructor = resolveConstructor(target);
964
+ const hookRef = {
965
+ propertyKey,
966
+ type,
967
+ ...description ? { description } : {},
968
+ ...hookOptions ? { options: hookOptions } : {}
969
+ };
970
+ recordFeatureHook(constructor, hookRef);
971
+ };
972
+ };
973
+ }
974
+ function resolveConstructor(target) {
975
+ const ctor = target.constructor;
976
+ if (typeof ctor !== "function") {
977
+ throw new Error("Decorated target does not expose a constructor");
978
+ }
979
+ return ctor;
980
+ }
981
+ return {
982
+ Feature,
983
+ Rule,
984
+ Scenario,
985
+ Given: createStepDecorator("Given"),
986
+ When: createStepDecorator("When"),
987
+ Then: createStepDecorator("Then"),
988
+ And: createStepDecorator("And"),
989
+ But: createStepDecorator("But"),
990
+ BeforeFeature: createFeatureHookDecorator("beforeFeature"),
991
+ AfterFeature: createFeatureHookDecorator("afterFeature"),
992
+ BeforeRule: createRuleHookDecorator("beforeRule"),
993
+ AfterRule: createRuleHookDecorator("afterRule"),
994
+ BeforeScenario: createScenarioHookDecorator("beforeScenario"),
995
+ AfterScenario: createScenarioHookDecorator("afterScenario"),
996
+ BeforeScenarioOutline: createScenarioHookDecorator("beforeScenarioOutline"),
997
+ AfterScenarioOutline: createScenarioHookDecorator("afterScenarioOutline")
998
+ };
999
+ }
1000
+ var WORLD_TOKEN = injection.createToken(
1001
+ "@autometa/runner/world"
1002
+ );
1003
+
1004
+ // src/bindings/create-bindings-ts.ts
1005
+ var BINDING_METADATA_KEY = Symbol("autometa:binding");
1006
+ var INJECT_PARAM_KEY = "autometa:inject_param";
1007
+ function createBindingsTS(stepsEnvironment) {
1008
+ if (typeof Reflect === "undefined" || typeof Reflect.getMetadata !== "function") {
1009
+ throw new Error(
1010
+ "bindingsTS() requires reflect-metadata. Add `import 'reflect-metadata'` at the top of your step-definitions file."
1011
+ );
1012
+ }
1013
+ const globalContainer = injection.createContainer();
1014
+ const { Inject, LazyInject } = injection.createDecorators(globalContainer);
1015
+ const { Given: GivenFn, When: WhenFn, Then: ThenFn, And: AndFn, But: BothFn } = stepsEnvironment;
1016
+ const instanceCache = /* @__PURE__ */ new WeakMap();
1017
+ const containerCache = /* @__PURE__ */ new WeakMap();
1018
+ function getScenarioContainer(world) {
1019
+ const worldObj = world;
1020
+ let container = containerCache.get(worldObj);
1021
+ if (!container) {
1022
+ container = globalContainer.createChild();
1023
+ container.registerValue(WORLD_TOKEN, world);
1024
+ containerCache.set(worldObj, container);
1025
+ }
1026
+ return container;
1027
+ }
1028
+ function getStepInstance(BindingClass, world) {
1029
+ const worldObj = world;
1030
+ let cache = instanceCache.get(worldObj);
1031
+ if (!cache) {
1032
+ cache = /* @__PURE__ */ new Map();
1033
+ instanceCache.set(worldObj, cache);
1034
+ }
1035
+ let instance = cache.get(BindingClass);
1036
+ if (instance) {
1037
+ return instance;
1038
+ }
1039
+ const container = getScenarioContainer(world);
1040
+ instance = container.resolve(BindingClass);
1041
+ cache.set(BindingClass, instance);
1042
+ return instance;
1043
+ }
1044
+ function getBindingMetadata(target) {
1045
+ let metadata = Reflect.getMetadata(BINDING_METADATA_KEY, target);
1046
+ if (!metadata) {
1047
+ metadata = { steps: [] };
1048
+ Reflect.defineMetadata(BINDING_METADATA_KEY, metadata, target);
1049
+ }
1050
+ return metadata;
1051
+ }
1052
+ function getBindingSteps(target) {
1053
+ const proto = target.prototype;
1054
+ return Reflect.getMetadata(BINDING_METADATA_KEY, target) ?? (proto ? Reflect.getMetadata(BINDING_METADATA_KEY, proto) : void 0);
1055
+ }
1056
+ function registerBindingClass(BindingClass) {
1057
+ const metadata = getBindingSteps(BindingClass);
1058
+ if (!metadata) {
1059
+ return;
1060
+ }
1061
+ for (const step of metadata.steps) {
1062
+ const handler = (...args) => {
1063
+ const world = args[args.length - 1];
1064
+ const stepArgs = args.slice(0, -1);
1065
+ const instance = getStepInstance(BindingClass, world);
1066
+ const method = instance[step.propertyKey];
1067
+ if (typeof method !== "function") {
1068
+ throw new Error(`Step method ${String(step.propertyKey)} is not a function`);
1069
+ }
1070
+ return method.apply(instance, stepArgs);
1071
+ };
1072
+ switch (step.keyword) {
1073
+ case "Given":
1074
+ GivenFn(step.expression, handler);
1075
+ break;
1076
+ case "When":
1077
+ WhenFn(step.expression, handler);
1078
+ break;
1079
+ case "Then":
1080
+ ThenFn(step.expression, handler);
1081
+ break;
1082
+ case "And":
1083
+ AndFn(step.expression, handler);
1084
+ break;
1085
+ case "But":
1086
+ BothFn(step.expression, handler);
1087
+ break;
1088
+ }
1089
+ }
1090
+ }
1091
+ function Binding() {
1092
+ return (target) => {
1093
+ const existing = Reflect.getMetadata(BINDING_METADATA_KEY, target.prototype);
1094
+ if (existing) {
1095
+ Reflect.defineMetadata(BINDING_METADATA_KEY, existing, target);
1096
+ }
1097
+ const paramTokens = Reflect.getMetadata(INJECT_PARAM_KEY, target);
1098
+ const deps = [];
1099
+ if (paramTokens) {
1100
+ const maxIndex = Math.max(...paramTokens.keys());
1101
+ for (let i = 0; i <= maxIndex; i++) {
1102
+ const token = paramTokens.get(i);
1103
+ if (token) {
1104
+ deps[i] = token;
1105
+ }
1106
+ }
1107
+ }
1108
+ globalContainer.registerClass(target, {
1109
+ scope: injection.Scope.TRANSIENT,
1110
+ deps
1111
+ });
1112
+ registerBindingClass(target);
1113
+ };
1114
+ }
1115
+ function createStepDecorator(keyword) {
1116
+ return (expression) => {
1117
+ return (target, propertyKey, _descriptor) => {
1118
+ const metadata = getBindingMetadata(target);
1119
+ metadata.steps.push({
1120
+ propertyKey,
1121
+ keyword,
1122
+ expression
1123
+ });
1124
+ };
1125
+ };
1126
+ }
1127
+ function Injectable(options) {
1128
+ return (target) => {
1129
+ globalContainer.registerClass(target, {
1130
+ scope: options?.scope ?? injection.Scope.TRANSIENT
1131
+ });
1132
+ };
1133
+ }
1134
+ return {
1135
+ Binding,
1136
+ Given: createStepDecorator("Given"),
1137
+ When: createStepDecorator("When"),
1138
+ Then: createStepDecorator("Then"),
1139
+ And: createStepDecorator("And"),
1140
+ But: createStepDecorator("But"),
1141
+ Injectable,
1142
+ Inject,
1143
+ LazyInject,
1144
+ container: globalContainer
1145
+ };
1146
+ }
1147
+ function coordinateRunnerFeature(options) {
1148
+ const {
1149
+ environment,
1150
+ feature,
1151
+ config,
1152
+ runtime,
1153
+ plan,
1154
+ adapterFactory,
1155
+ planBuilder,
1156
+ registerPlan,
1157
+ featureScope,
1158
+ hookLogger
1159
+ } = options;
1160
+ const scopePlan = plan ?? environment.getPlan();
1161
+ return coordinator.coordinateFeature({
1162
+ feature,
1163
+ scopePlan,
1164
+ config,
1165
+ ...runtime ? { runtime } : {},
1166
+ ...adapterFactory ? { adapterFactory } : {},
1167
+ ...planBuilder ? { planBuilder } : {},
1168
+ ...registerPlan ? { registerPlan } : {},
1169
+ ...featureScope ? { featureScope } : {},
1170
+ ...hookLogger ? { hookLogger } : {}
1171
+ });
1172
+ }
1173
+
1174
+ // src/builder/create-runner-builder.ts
1175
+ function normalizeWorldFactory(factory) {
1176
+ const callable = factory;
1177
+ if (callable.length >= 1) {
1178
+ return factory;
1179
+ }
1180
+ return async (_context) => await callable();
1181
+ }
1182
+ var WORLD_INHERIT_KEYS = Symbol("autometa.runner.world.inherit");
1183
+ var STEPS_ENVIRONMENT_META = Symbol.for(
1184
+ "autometa.runner.steps.environment.meta"
1185
+ );
1186
+ var App = {
1187
+ compositionRoot(ctor, options) {
1188
+ return async (context) => {
1189
+ const { setup, ...registration } = options ?? {};
1190
+ if (setup) {
1191
+ await setup(context);
1192
+ }
1193
+ const registered = context.getRegisteredApp?.();
1194
+ if (registered !== void 0) {
1195
+ return registered;
1196
+ }
1197
+ const container = context.container;
1198
+ if (typeof container.isRegistered === "function" && container.isRegistered(ctor)) {
1199
+ return context.resolve(ctor);
1200
+ }
1201
+ return context.registerApp(
1202
+ ctor,
1203
+ registration
1204
+ );
1205
+ };
1206
+ }
1207
+ };
1208
+ function createRunnerBuilder(initial) {
1209
+ const state = initializeState(initial);
1210
+ return new RunnerBuilderImpl(state);
1211
+ }
1212
+ var RunnerBuilderImpl = class _RunnerBuilderImpl {
1213
+ constructor(state) {
1214
+ this.state = state;
1215
+ }
1216
+ fork() {
1217
+ const next = cloneBuilderState(this.state);
1218
+ return new _RunnerBuilderImpl(next);
1219
+ }
1220
+ derivable() {
1221
+ if (!this.state.derivedBuilders) {
1222
+ this.state.derivedBuilders = /* @__PURE__ */ new Map();
1223
+ }
1224
+ return this;
1225
+ }
1226
+ group(key) {
1227
+ const trimmed = key.trim();
1228
+ if (!trimmed) {
1229
+ throw new Error("group key must be a non-empty string");
1230
+ }
1231
+ if (!this.state.derivedBuilders) {
1232
+ this.state.derivedBuilders = /* @__PURE__ */ new Map();
1233
+ }
1234
+ const existing = this.state.derivedBuilders.get(trimmed);
1235
+ if (existing) {
1236
+ return new _RunnerBuilderImpl(existing);
1237
+ }
1238
+ const derived = cloneBuilderState(this.state);
1239
+ derived.stepsEnvironmentMeta = { kind: "group", group: trimmed };
1240
+ this.state.derivedBuilders.set(trimmed, derived);
1241
+ return new _RunnerBuilderImpl(derived);
1242
+ }
1243
+ extendWorld(value) {
1244
+ const baseFactory = this.state.worldFactory;
1245
+ const extensionFactory = typeof value === "function" ? normalizeWorldFactory(
1246
+ value
1247
+ ) : value ? createDefaultsWorldFactory(ensureWorldDefaults(value)) : async () => ({});
1248
+ const baseInheritance = getWorldInheritance(baseFactory);
1249
+ const extensionInheritance = getWorldInheritance(extensionFactory);
1250
+ const inheritance = baseInheritance || extensionInheritance ? /* @__PURE__ */ new Set([
1251
+ ...baseInheritance ? Array.from(baseInheritance) : [],
1252
+ ...extensionInheritance ? Array.from(extensionInheritance) : []
1253
+ ]) : void 0;
1254
+ const merged = async (context) => {
1255
+ const base = baseFactory ? await baseFactory(context) : {};
1256
+ const extension = await extensionFactory(
1257
+ context
1258
+ );
1259
+ const baseObj = ensureWorldObject(base);
1260
+ const extObj = ensureWorldObject(extension);
1261
+ return { ...baseObj, ...extObj };
1262
+ };
1263
+ if (inheritance && inheritance.size > 0) {
1264
+ Object.defineProperty(merged, WORLD_INHERIT_KEYS, {
1265
+ value: inheritance,
1266
+ writable: false,
1267
+ enumerable: false,
1268
+ configurable: false
1269
+ });
1270
+ }
1271
+ this.state.worldFactory = merged;
1272
+ delete this.state.ensureFactory;
1273
+ invalidateCaches(this.state);
1274
+ return new _RunnerBuilderImpl(this.state);
1275
+ }
1276
+ extendApp(app) {
1277
+ const next = normalizeAppFactory(app);
1278
+ const previous = this.state.appFactory;
1279
+ const chained = async (context) => {
1280
+ let currentApp;
1281
+ const readRegisteredApp = () => {
1282
+ const anyContext = context;
1283
+ return typeof anyContext.getRegisteredApp === "function" ? anyContext.getRegisteredApp() : void 0;
1284
+ };
1285
+ const updateWorldApp = (value) => {
1286
+ if (!value) {
1287
+ return;
1288
+ }
1289
+ const world = context.world;
1290
+ if (world && typeof world === "object") {
1291
+ world.app = value;
1292
+ }
1293
+ };
1294
+ if (previous) {
1295
+ const result = await previous(context);
1296
+ currentApp = result ?? readRegisteredApp();
1297
+ updateWorldApp(currentApp);
1298
+ }
1299
+ const nextResult = await next(context);
1300
+ const nextApp = nextResult ?? readRegisteredApp();
1301
+ if (nextApp !== void 0) {
1302
+ currentApp = nextApp;
1303
+ updateWorldApp(currentApp);
1304
+ }
1305
+ return currentApp;
1306
+ };
1307
+ this.state.appFactory = chained;
1308
+ delete this.state.ensureFactory;
1309
+ invalidateCaches(this.state);
1310
+ return new _RunnerBuilderImpl(this.state);
1311
+ }
1312
+ configure(update) {
1313
+ if (typeof update === "function") {
1314
+ const current = collectCurrentOptions(this.state);
1315
+ const merged = update(current);
1316
+ applyOptions(this.state, merged);
1317
+ return new _RunnerBuilderImpl(
1318
+ this.state
1319
+ );
1320
+ }
1321
+ applyOptions(this.state, update);
1322
+ return new _RunnerBuilderImpl(
1323
+ this.state
1324
+ );
1325
+ }
1326
+ expressionMap() {
1327
+ return new _RunnerBuilderImpl(
1328
+ this.state
1329
+ );
1330
+ }
1331
+ withWorld(value) {
1332
+ if (typeof value === "function") {
1333
+ this.state.worldFactory = normalizeWorldFactory(
1334
+ value
1335
+ );
1336
+ } else if (value) {
1337
+ const validated = ensureWorldDefaults(value);
1338
+ this.state.worldFactory = createDefaultsWorldFactory(validated);
1339
+ } else {
1340
+ this.state.worldFactory = async (_context) => ({});
1341
+ }
1342
+ delete this.state.ensureFactory;
1343
+ invalidateCaches(this.state);
1344
+ return new _RunnerBuilderImpl(this.state);
1345
+ }
1346
+ app(app) {
1347
+ this.state.appFactory = normalizeAppFactory(app);
1348
+ delete this.state.ensureFactory;
1349
+ invalidateCaches(this.state);
1350
+ return new _RunnerBuilderImpl(this.state);
1351
+ }
1352
+ assertions(setup) {
1353
+ this.state.ensureFactory = setup(assertions.ensure);
1354
+ invalidateCaches(this.state);
1355
+ return new _RunnerBuilderImpl(
1356
+ this.state
1357
+ );
1358
+ }
1359
+ assertionPlugins(plugins) {
1360
+ return this.assertions(
1361
+ (ensureInvoke) => {
1362
+ const factory = assertions.createEnsureFactory(
1363
+ ensureInvoke,
1364
+ plugins
1365
+ );
1366
+ return createImplicitEnsureProxy(factory);
1367
+ }
1368
+ );
1369
+ }
1370
+ parameterTypes(definitions) {
1371
+ const current = this.state.options.parameterTypes ?? [];
1372
+ this.state.options.parameterTypes = [
1373
+ ...current,
1374
+ ...definitions
1375
+ ];
1376
+ invalidateCaches(this.state);
1377
+ return new _RunnerBuilderImpl(this.state);
1378
+ }
1379
+ steps() {
1380
+ return ensureSteps(this.state);
1381
+ }
1382
+ decorators() {
1383
+ return ensureDecorators(this.state);
1384
+ }
1385
+ bindingsTS() {
1386
+ return ensureBindingsTS(this.state);
1387
+ }
1388
+ };
1389
+ function initializeState(initial) {
1390
+ if (!initial) {
1391
+ return {
1392
+ options: {},
1393
+ stepsEnvironmentMeta: { kind: "root" }
1394
+ };
1395
+ }
1396
+ const { worldFactory, ...rest } = initial;
1397
+ const state = {
1398
+ options: { ...rest },
1399
+ stepsEnvironmentMeta: { kind: "root" }
1400
+ };
1401
+ if (worldFactory) {
1402
+ state.worldFactory = normalizeWorldFactory(
1403
+ worldFactory
1404
+ );
1405
+ }
1406
+ return state;
1407
+ }
1408
+ function cloneBuilderState(source) {
1409
+ const next = {
1410
+ options: cloneWithFallback(source.options)
1411
+ };
1412
+ if (source.stepsEnvironmentMeta) {
1413
+ next.stepsEnvironmentMeta = source.stepsEnvironmentMeta;
1414
+ }
1415
+ if (source.worldFactory) {
1416
+ next.worldFactory = source.worldFactory;
1417
+ }
1418
+ if (source.appFactory) {
1419
+ next.appFactory = source.appFactory;
1420
+ }
1421
+ if (source.ensureFactory) {
1422
+ next.ensureFactory = source.ensureFactory;
1423
+ }
1424
+ return next;
1425
+ }
1426
+ function collectCurrentOptions(state) {
1427
+ const options = {
1428
+ ...state.options
1429
+ };
1430
+ if (state.worldFactory) {
1431
+ options.worldFactory = state.worldFactory;
1432
+ }
1433
+ return options;
1434
+ }
1435
+ function applyOptions(state, options) {
1436
+ const { worldFactory, ...rest } = options;
1437
+ state.options = {
1438
+ ...state.options,
1439
+ ...rest
1440
+ };
1441
+ if ("worldFactory" in options) {
1442
+ if (worldFactory) {
1443
+ state.worldFactory = normalizeWorldFactory(
1444
+ worldFactory
1445
+ );
1446
+ } else {
1447
+ delete state.worldFactory;
1448
+ }
1449
+ delete state.ensureFactory;
1450
+ }
1451
+ invalidateCaches(state);
1452
+ }
1453
+ function normalizeAppFactory(app) {
1454
+ if (typeof app === "function") {
1455
+ if (app.length > 0) {
1456
+ return async (context) => await app(
1457
+ context
1458
+ );
1459
+ }
1460
+ return async () => await app();
1461
+ }
1462
+ return async () => app;
1463
+ }
1464
+ function createDefaultsWorldFactory(defaults) {
1465
+ const inheritance = extractWorldInheritance(defaults);
1466
+ const snapshot = cloneDefaults(defaults);
1467
+ const factory = async () => cloneDefaults(snapshot);
1468
+ if (inheritance.size > 0) {
1469
+ Object.defineProperty(factory, WORLD_INHERIT_KEYS, {
1470
+ value: inheritance,
1471
+ writable: false,
1472
+ enumerable: false,
1473
+ configurable: false
1474
+ });
1475
+ }
1476
+ return factory;
1477
+ }
1478
+ function ensureWorldDefaults(value) {
1479
+ if (!value || typeof value !== "object") {
1480
+ throw new TypeError(
1481
+ "withWorld defaults must be a non-null object"
1482
+ );
1483
+ }
1484
+ return value;
1485
+ }
1486
+ function cloneDefaults(defaults) {
1487
+ const structuredCloneFn = globalThis.structuredClone;
1488
+ if (structuredCloneFn) {
1489
+ try {
1490
+ return structuredCloneFn(defaults);
1491
+ } catch {
1492
+ }
1493
+ }
1494
+ return cloneWithFallback(defaults);
1495
+ }
1496
+ function extractWorldInheritance(defaults) {
1497
+ const inherit = defaults[WORLD_INHERIT_KEYS];
1498
+ if (!inherit || inherit.length === 0) {
1499
+ return /* @__PURE__ */ new Set();
1500
+ }
1501
+ const inheritance = new Set(inherit);
1502
+ return inheritance;
1503
+ }
1504
+ function getWorldInheritance(factory) {
1505
+ if (!factory) {
1506
+ return void 0;
1507
+ }
1508
+ const withMetadata = factory;
1509
+ return withMetadata[WORLD_INHERIT_KEYS];
1510
+ }
1511
+ function cloneWithFallback(value) {
1512
+ if (Array.isArray(value)) {
1513
+ return value.map((item) => cloneWithFallback(item));
1514
+ }
1515
+ if (value instanceof Map) {
1516
+ return new Map(
1517
+ Array.from(value.entries(), ([key, entry]) => [key, cloneWithFallback(entry)])
1518
+ );
1519
+ }
1520
+ if (value instanceof Set) {
1521
+ return new Set(Array.from(value.values(), (entry) => cloneWithFallback(entry)));
1522
+ }
1523
+ if (value && typeof value === "object") {
1524
+ const prototype = Object.getPrototypeOf(value);
1525
+ if (prototype === Object.prototype || prototype === null) {
1526
+ const result = {};
1527
+ for (const [key, entry] of Object.entries(value)) {
1528
+ result[key] = cloneWithFallback(entry);
1529
+ }
1530
+ return result;
1531
+ }
1532
+ }
1533
+ return value;
1534
+ }
1535
+ function invalidateCaches(state) {
1536
+ delete state.stepsCache;
1537
+ delete state.decoratorsCache;
1538
+ delete state.bindingsTSCache;
1539
+ }
1540
+ function ensureSteps(state) {
1541
+ let cache = state.stepsCache;
1542
+ if (!cache) {
1543
+ const options = buildRunnerOptions(state, { includeParameterTypes: true });
1544
+ const environment = createRunner(options);
1545
+ const globals = createGlobalRunner();
1546
+ globals.useEnvironment(environment);
1547
+ const ensureFactory = resolveEnsureFactory(state);
1548
+ const surface = attachStepsHelpers(
1549
+ state,
1550
+ environment,
1551
+ globals,
1552
+ ensureFactory
1553
+ );
1554
+ try {
1555
+ Object.defineProperty(surface, STEPS_ENVIRONMENT_META, {
1556
+ value: state.stepsEnvironmentMeta ?? { kind: "root" },
1557
+ writable: false,
1558
+ enumerable: false,
1559
+ configurable: false
1560
+ });
1561
+ } catch {
1562
+ }
1563
+ cache = {
1564
+ environment,
1565
+ globals,
1566
+ surface,
1567
+ ensureFactory
1568
+ };
1569
+ state.stepsCache = cache;
1570
+ }
1571
+ return cache.surface;
1572
+ }
1573
+ function ensureDecorators(state) {
1574
+ let cache = state.decoratorsCache;
1575
+ if (!cache) {
1576
+ const steps = ensureSteps(state);
1577
+ const options = buildRunnerOptions(state, {
1578
+ includeParameterTypes: false
1579
+ });
1580
+ const decoratorOptions = {
1581
+ ...options,
1582
+ parameterRegistry: steps.parameterRegistry,
1583
+ registerDefaultParameterTypes: false
1584
+ };
1585
+ const environment = createDecoratorRunner(decoratorOptions);
1586
+ const decorators = createRunnerDecorators(environment);
1587
+ const surface = attachDecoratorEnvironment(decorators, environment);
1588
+ cache = {
1589
+ environment,
1590
+ surface
1591
+ };
1592
+ state.decoratorsCache = cache;
1593
+ }
1594
+ return cache.surface;
1595
+ }
1596
+ function ensureBindingsTS(state) {
1597
+ let cache = state.bindingsTSCache;
1598
+ if (!cache) {
1599
+ const stepsEnv = ensureSteps(state);
1600
+ const surface = createBindingsTS(stepsEnv);
1601
+ cache = {
1602
+ surface
1603
+ };
1604
+ state.bindingsTSCache = cache;
1605
+ }
1606
+ return cache.surface;
1607
+ }
1608
+ function buildRunnerOptions(state, options) {
1609
+ const includeParameterTypes = options?.includeParameterTypes ?? true;
1610
+ const base = {
1611
+ ...state.options
1612
+ };
1613
+ if (!includeParameterTypes && "parameterTypes" in base) {
1614
+ delete base.parameterTypes;
1615
+ }
1616
+ const featureRegistry = ensureFeatureRegistry(state);
1617
+ const worldFactory = composeWorldFactory(
1618
+ state.worldFactory,
1619
+ state.appFactory,
1620
+ featureRegistry
1621
+ );
1622
+ if (worldFactory) {
1623
+ base.worldFactory = worldFactory;
1624
+ } else if ("worldFactory" in base) {
1625
+ delete base.worldFactory;
1626
+ }
1627
+ return base;
1628
+ }
1629
+ function composeWorldFactory(baseFactory, appFactory, featureRegistry) {
1630
+ if (!baseFactory && !appFactory && !featureRegistry) {
1631
+ return void 0;
1632
+ }
1633
+ const factory = baseFactory ?? (async (_context) => ({}));
1634
+ const inheritance = getWorldInheritance(baseFactory);
1635
+ return async (context) => {
1636
+ const container = injection.createContainer();
1637
+ const world = await factory(context);
1638
+ const asObject = ensureWorldObject(world);
1639
+ const parentObject = context.parent !== void 0 ? ensureWorldObject(context.parent) : void 0;
1640
+ const mergedWorld = parentObject !== void 0 ? mergeWorldWithParent(asObject, parentObject, inheritance) : asObject;
1641
+ attachWorldAncestors(mergedWorld, parentObject);
1642
+ attachFeatureRegistry(mergedWorld, featureRegistry);
1643
+ attachContainer(mergedWorld, container);
1644
+ attachRuntime(mergedWorld);
1645
+ attachWorldToJson(mergedWorld);
1646
+ container.registerValue(WORLD_TOKEN, mergedWorld, {
1647
+ scope: injection.Scope.SCENARIO
1648
+ });
1649
+ if (appFactory) {
1650
+ const resolvedAppFactory = appFactory;
1651
+ const composer = createAppFactoryContext(container, mergedWorld);
1652
+ const appResult = await resolvedAppFactory(composer);
1653
+ const app = appResult ?? composer.getRegisteredApp();
1654
+ if (app === void 0) {
1655
+ throw new Error(
1656
+ "App factory did not return an application instance. Use return or registerApp to provide one."
1657
+ );
1658
+ }
1659
+ mergedWorld.app = app;
1660
+ }
1661
+ return mergedWorld;
1662
+ };
1663
+ }
1664
+ function attachStepsHelpers(state, environment, globals, ensureFactory) {
1665
+ if (!("globals" in environment)) {
1666
+ Object.defineProperty(environment, "globals", {
1667
+ value: globals,
1668
+ enumerable: true,
1669
+ configurable: true
1670
+ });
1671
+ }
1672
+ if (!("coordinateFeature" in environment)) {
1673
+ Object.defineProperty(environment, "coordinateFeature", {
1674
+ value: (options) => {
1675
+ const registry = ensureFeatureRegistry(state);
1676
+ if (options.feature) {
1677
+ registry.remember(options.feature);
1678
+ }
1679
+ return coordinateRunnerFeature({
1680
+ environment,
1681
+ ...options
1682
+ });
1683
+ },
1684
+ enumerable: true,
1685
+ configurable: true
1686
+ });
1687
+ }
1688
+ if (!("ensure" in environment)) {
1689
+ Object.defineProperty(environment, "ensure", {
1690
+ value: ensureFactory,
1691
+ enumerable: true,
1692
+ configurable: true
1693
+ });
1694
+ }
1695
+ return environment;
1696
+ }
1697
+ function resolveEnsureFactory(state) {
1698
+ if (state.ensureFactory) {
1699
+ return state.ensureFactory;
1700
+ }
1701
+ const factory = assertions.createDefaultEnsureFactory();
1702
+ const proxy = createImplicitEnsureProxy(factory);
1703
+ state.ensureFactory = proxy;
1704
+ return proxy;
1705
+ }
1706
+ function attachDecoratorEnvironment(decorators, environment) {
1707
+ if (!("environment" in decorators)) {
1708
+ Object.defineProperty(decorators, "environment", {
1709
+ value: environment,
1710
+ enumerable: true,
1711
+ configurable: true
1712
+ });
1713
+ }
1714
+ return decorators;
1715
+ }
1716
+ function ensureWorldObject(world) {
1717
+ if (world && typeof world === "object") {
1718
+ return world;
1719
+ }
1720
+ return {};
1721
+ }
1722
+ function attachContainer(world, container) {
1723
+ const descriptor = {
1724
+ value: container,
1725
+ configurable: true,
1726
+ enumerable: false,
1727
+ writable: false
1728
+ };
1729
+ if (!Reflect.has(world, "di")) {
1730
+ Object.defineProperty(world, "di", descriptor);
1731
+ }
1732
+ if (!Reflect.has(world, "container")) {
1733
+ Object.defineProperty(world, "container", descriptor);
1734
+ }
1735
+ }
1736
+ function createAppFactoryContext(container, world) {
1737
+ let registeredApp;
1738
+ function withScenarioScope(options) {
1739
+ return {
1740
+ scope: options?.scope ?? injection.Scope.SCENARIO,
1741
+ ...options?.tags ? { tags: [...options.tags] } : {},
1742
+ ...options?.deps ? { deps: [...options.deps] } : {},
1743
+ ...options?.props ? { props: options.props } : {}
1744
+ };
1745
+ }
1746
+ const context = {
1747
+ container,
1748
+ world,
1749
+ getRegisteredApp() {
1750
+ return registeredApp;
1751
+ },
1752
+ registerClass(target, options) {
1753
+ const { scope, tags, deps, inject } = options ?? {};
1754
+ let propsMap;
1755
+ if (inject) {
1756
+ const keys = Reflect.ownKeys(inject);
1757
+ if (keys.length > 0) {
1758
+ const entries = [];
1759
+ for (const key of keys) {
1760
+ const descriptor = inject[key];
1761
+ if (!descriptor) {
1762
+ continue;
1763
+ }
1764
+ entries.push([key, descriptor]);
1765
+ }
1766
+ if (entries.length > 0) {
1767
+ propsMap = Object.fromEntries(entries.map(([key, descriptor]) => {
1768
+ if (typeof descriptor === "object" && "token" in descriptor) {
1769
+ return [key, {
1770
+ token: descriptor.token,
1771
+ ...descriptor.lazy ? { lazy: descriptor.lazy } : {}
1772
+ }];
1773
+ }
1774
+ return [key, descriptor];
1775
+ }));
1776
+ }
1777
+ }
1778
+ }
1779
+ const registration = {
1780
+ scope: scope ?? injection.Scope.SCENARIO,
1781
+ ...tags ? { tags: [...tags] } : {},
1782
+ ...deps ? { deps: [...deps] } : {},
1783
+ ...propsMap ? { props: propsMap } : {}
1784
+ };
1785
+ container.registerClass(target, registration);
1786
+ return context;
1787
+ },
1788
+ registerValue(identifier, value, options) {
1789
+ container.registerValue(identifier, value, withScenarioScope(options));
1790
+ return context;
1791
+ },
1792
+ registerFactory(identifier, factory, options) {
1793
+ container.registerFactory(identifier, factory, withScenarioScope(options));
1794
+ return context;
1795
+ },
1796
+ registerToken(token, target, options) {
1797
+ container.registerToken(token, target, withScenarioScope(options));
1798
+ return context;
1799
+ },
1800
+ async registerApp(target, options) {
1801
+ context.registerClass(target, options);
1802
+ const instance = container.resolve(target);
1803
+ registeredApp = instance;
1804
+ if (options?.configure) {
1805
+ await options.configure(instance, context);
1806
+ }
1807
+ return instance;
1808
+ },
1809
+ resolve(identifier) {
1810
+ return container.resolve(identifier);
1811
+ }
1812
+ };
1813
+ return context;
1814
+ }
1815
+ function attachRuntime(world) {
1816
+ if (Reflect.has(world, "runtime")) {
1817
+ return;
1818
+ }
1819
+ Object.defineProperty(world, "runtime", {
1820
+ get() {
1821
+ return executor.createStepRuntime(this);
1822
+ },
1823
+ enumerable: false,
1824
+ configurable: true
1825
+ });
1826
+ }
1827
+ var WORLD_JSON_EXCLUDE_KEYS = /* @__PURE__ */ new Set([
1828
+ "app",
1829
+ "di",
1830
+ "container",
1831
+ "runtime",
1832
+ "ancestors"
1833
+ ]);
1834
+ function attachWorldToJson(world) {
1835
+ if (Reflect.has(world, "toJSON")) {
1836
+ return;
1837
+ }
1838
+ Object.defineProperty(world, "toJSON", {
1839
+ value: () => {
1840
+ const stack = /* @__PURE__ */ new WeakSet();
1841
+ return toJsonSafeValue(world, 8, stack);
1842
+ },
1843
+ enumerable: false,
1844
+ configurable: true,
1845
+ writable: true
1846
+ });
1847
+ }
1848
+ function toJsonSafeValue(value, depth, stack) {
1849
+ if (value === null) {
1850
+ return null;
1851
+ }
1852
+ switch (typeof value) {
1853
+ case "boolean":
1854
+ case "number":
1855
+ case "string":
1856
+ return value;
1857
+ case "bigint":
1858
+ return value.toString();
1859
+ case "undefined":
1860
+ return "[undefined]";
1861
+ case "symbol":
1862
+ return value.toString();
1863
+ case "function":
1864
+ return "[Function]";
1865
+ case "object":
1866
+ break;
1867
+ default:
1868
+ return String(value);
1869
+ }
1870
+ if (depth <= 0) {
1871
+ return "[MaxDepth]";
1872
+ }
1873
+ const obj = value;
1874
+ if (stack.has(obj)) {
1875
+ return "[Circular]";
1876
+ }
1877
+ if (Array.isArray(obj)) {
1878
+ stack.add(obj);
1879
+ try {
1880
+ return obj.map((entry) => toJsonSafeValue(entry, depth - 1, stack));
1881
+ } finally {
1882
+ stack.delete(obj);
1883
+ }
1884
+ }
1885
+ if (obj instanceof Date) {
1886
+ return obj.toISOString();
1887
+ }
1888
+ if (obj instanceof Error) {
1889
+ return {
1890
+ name: obj.name,
1891
+ message: obj.message,
1892
+ stack: obj.stack ?? ""
1893
+ };
1894
+ }
1895
+ if (obj instanceof Map) {
1896
+ stack.add(obj);
1897
+ try {
1898
+ return {
1899
+ "[Map]": Array.from(obj.entries()).map(([key, entry]) => ({
1900
+ key: toJsonSafeValue(key, depth - 1, stack),
1901
+ value: toJsonSafeValue(entry, depth - 1, stack)
1902
+ }))
1903
+ };
1904
+ } finally {
1905
+ stack.delete(obj);
1906
+ }
1907
+ }
1908
+ if (obj instanceof Set) {
1909
+ stack.add(obj);
1910
+ try {
1911
+ return { "[Set]": Array.from(obj.values()).map((entry) => toJsonSafeValue(entry, depth - 1, stack)) };
1912
+ } finally {
1913
+ stack.delete(obj);
1914
+ }
1915
+ }
1916
+ stack.add(obj);
1917
+ try {
1918
+ const record = obj;
1919
+ const result = {};
1920
+ for (const [key, entry] of Object.entries(record)) {
1921
+ if (WORLD_JSON_EXCLUDE_KEYS.has(key)) {
1922
+ continue;
1923
+ }
1924
+ result[key] = toJsonSafeValue(entry, depth - 1, stack);
1925
+ }
1926
+ return result;
1927
+ } finally {
1928
+ stack.delete(obj);
1929
+ }
1930
+ }
1931
+ function attachFeatureRegistry(world, featureRegistry) {
1932
+ if (!featureRegistry) {
1933
+ return;
1934
+ }
1935
+ world.features = featureRegistry.snapshot();
1936
+ }
1937
+ var PARENT_WORLD_EXCLUDE_KEYS = /* @__PURE__ */ new Set([
1938
+ "di",
1939
+ "container",
1940
+ "runtime",
1941
+ "app",
1942
+ "ancestors"
1943
+ ]);
1944
+ function mergeWorldWithParent(child, parent, inheritance) {
1945
+ if (!parent || !inheritance || inheritance.size === 0) {
1946
+ return child;
1947
+ }
1948
+ for (const key of inheritance) {
1949
+ if (PARENT_WORLD_EXCLUDE_KEYS.has(key)) {
1950
+ continue;
1951
+ }
1952
+ if (!Reflect.has(parent, key)) {
1953
+ continue;
1954
+ }
1955
+ const descriptor = Object.getOwnPropertyDescriptor(parent, key);
1956
+ if (descriptor) {
1957
+ Object.defineProperty(child, key, descriptor);
1958
+ }
1959
+ }
1960
+ return child;
1961
+ }
1962
+ function attachWorldAncestors(world, parent) {
1963
+ const parentAncestors = parent && Reflect.has(parent, "ancestors") ? parent.ancestors : void 0;
1964
+ const lineage = parent ? [
1965
+ parent,
1966
+ ...Array.isArray(parentAncestors) ? parentAncestors : []
1967
+ ] : [];
1968
+ Object.defineProperty(world, "ancestors", {
1969
+ value: lineage,
1970
+ writable: false,
1971
+ enumerable: false,
1972
+ configurable: true
1973
+ });
1974
+ }
1975
+ function ensureFeatureRegistry(state) {
1976
+ if (!state.featureRegistry) {
1977
+ state.featureRegistry = createFeatureRegistry();
1978
+ }
1979
+ return state.featureRegistry;
1980
+ }
1981
+ function createFeatureRegistry() {
1982
+ const byId = /* @__PURE__ */ new Map();
1983
+ return {
1984
+ remember(feature) {
1985
+ const id = feature.uri ?? feature.name;
1986
+ if (!id || byId.has(id)) {
1987
+ return;
1988
+ }
1989
+ byId.set(id, feature);
1990
+ },
1991
+ snapshot() {
1992
+ return Array.from(byId.values());
1993
+ }
1994
+ };
1995
+ }
1996
+ function createImplicitEnsureProxy(factory) {
1997
+ return new Proxy(factory, {
1998
+ get(target, prop, receiver) {
1999
+ if (prop === "world") {
2000
+ return executor.tryGetWorld();
2001
+ }
2002
+ const world = executor.tryGetWorld();
2003
+ if (world) {
2004
+ const facade = factory(world);
2005
+ return Reflect.get(facade, prop, receiver);
2006
+ }
2007
+ return Reflect.get(target, prop, receiver);
2008
+ },
2009
+ apply(target, _thisArg, args) {
2010
+ const [arg, options] = args;
2011
+ const world = executor.tryGetWorld();
2012
+ if (world) {
2013
+ if (arg === world) {
2014
+ return factory(world);
2015
+ }
2016
+ const facade = factory(world);
2017
+ return facade(arg, options);
2018
+ }
2019
+ return factory(arg);
2020
+ }
2021
+ });
2022
+ }
2023
+
2024
+ // src/current.ts
2025
+ var stepsErrorMessage = "Runner steps surface has not been configured. Call setCurrentRunnerSteps() before accessing the shared runner surface.";
2026
+ var currentSteps;
2027
+ function setCurrentRunnerSteps(steps) {
2028
+ currentSteps = steps;
2029
+ }
2030
+ function getCurrentRunnerSteps() {
2031
+ if (!currentSteps) {
2032
+ throw new Error(stepsErrorMessage);
2033
+ }
2034
+ return currentSteps;
2035
+ }
2036
+ function clearCurrentRunnerSteps() {
2037
+ currentSteps = void 0;
2038
+ }
2039
+
2040
+ // src/global.ts
2041
+ var runnerInstance;
2042
+ function instantiateRunner(options) {
2043
+ return createGlobalRunner(options);
2044
+ }
2045
+ function requireConfigured(action) {
2046
+ if (!runnerInstance) {
2047
+ throw new Error(
2048
+ `Global runner has not been configured. ${action}`
2049
+ );
2050
+ }
2051
+ return runnerInstance;
2052
+ }
2053
+ function getGlobalRunner(options) {
2054
+ if (!runnerInstance) {
2055
+ runnerInstance = instantiateRunner(options);
2056
+ }
2057
+ return runnerInstance;
2058
+ }
2059
+ function configureGlobalRunner(options) {
2060
+ runnerInstance = instantiateRunner(options);
2061
+ return runnerInstance;
2062
+ }
2063
+ function resetGlobalRunner(options) {
2064
+ runnerInstance = instantiateRunner(options);
2065
+ return runnerInstance;
2066
+ }
2067
+ function disposeGlobalRunner() {
2068
+ runnerInstance = void 0;
2069
+ }
2070
+ function useGlobalRunnerEnvironment(environment) {
2071
+ const runner = requireConfigured(
2072
+ "Call configureGlobalRunner() before injecting environments."
2073
+ );
2074
+ return runner.useEnvironment(environment);
2075
+ }
2076
+ function getGlobalRunnerEnvironment() {
2077
+ const runner = requireConfigured(
2078
+ "Call configureGlobalRunner() before reading environments."
2079
+ );
2080
+ return runner.getEnvironment();
2081
+ }
2082
+ function getConfiguredGlobalRunner() {
2083
+ return requireConfigured(
2084
+ "Call configureGlobalRunner() before accessing runner APIs."
2085
+ );
2086
+ }
2087
+
2088
+ // src/cucumber-runner.ts
2089
+ var CucumberRunner = class {
2090
+ static builder(initial) {
2091
+ return createRunnerBuilder(initial);
2092
+ }
2093
+ static setSteps(steps) {
2094
+ setCurrentRunnerSteps(steps);
2095
+ }
2096
+ static steps() {
2097
+ return getCurrentRunnerSteps();
2098
+ }
2099
+ static clearSteps() {
2100
+ clearCurrentRunnerSteps();
2101
+ }
2102
+ };
2103
+
2104
+ Object.defineProperty(exports, 'Pending', {
2105
+ enumerable: true,
2106
+ get: function () { return executor.Pending; }
2107
+ });
2108
+ Object.defineProperty(exports, 'ScenarioPendingError', {
2109
+ enumerable: true,
2110
+ get: function () { return executor.ScenarioPendingError; }
2111
+ });
2112
+ Object.defineProperty(exports, 'ToDo', {
2113
+ enumerable: true,
2114
+ get: function () { return executor.ToDo; }
2115
+ });
2116
+ Object.defineProperty(exports, 'clearStepDocstring', {
2117
+ enumerable: true,
2118
+ get: function () { return executor.clearStepDocstring; }
2119
+ });
2120
+ Object.defineProperty(exports, 'clearStepTable', {
2121
+ enumerable: true,
2122
+ get: function () { return executor.clearStepTable; }
2123
+ });
2124
+ Object.defineProperty(exports, 'configureStepDocstrings', {
2125
+ enumerable: true,
2126
+ get: function () { return executor.configureStepDocstrings; }
2127
+ });
2128
+ Object.defineProperty(exports, 'configureStepTables', {
2129
+ enumerable: true,
2130
+ get: function () { return executor.configureStepTables; }
2131
+ });
2132
+ Object.defineProperty(exports, 'consumeDocstring', {
2133
+ enumerable: true,
2134
+ get: function () { return executor.consumeDocstring; }
2135
+ });
2136
+ Object.defineProperty(exports, 'consumeTable', {
2137
+ enumerable: true,
2138
+ get: function () { return executor.consumeTable; }
2139
+ });
2140
+ Object.defineProperty(exports, 'getDocstring', {
2141
+ enumerable: true,
2142
+ get: function () { return executor.getDocstring; }
2143
+ });
2144
+ Object.defineProperty(exports, 'getDocstringInfo', {
2145
+ enumerable: true,
2146
+ get: function () { return executor.getDocstringInfo; }
2147
+ });
2148
+ Object.defineProperty(exports, 'getDocstringMediaType', {
2149
+ enumerable: true,
2150
+ get: function () { return executor.getDocstringMediaType; }
2151
+ });
2152
+ Object.defineProperty(exports, 'getRawTable', {
2153
+ enumerable: true,
2154
+ get: function () { return executor.getRawTable; }
2155
+ });
2156
+ Object.defineProperty(exports, 'getTable', {
2157
+ enumerable: true,
2158
+ get: function () { return executor.getTable; }
2159
+ });
2160
+ Object.defineProperty(exports, 'isScenarioPendingError', {
2161
+ enumerable: true,
2162
+ get: function () { return executor.isScenarioPendingError; }
2163
+ });
2164
+ Object.defineProperty(exports, 'markScenarioPending', {
2165
+ enumerable: true,
2166
+ get: function () { return executor.markScenarioPending; }
2167
+ });
2168
+ Object.defineProperty(exports, 'resetStepDocstringConfig', {
2169
+ enumerable: true,
2170
+ get: function () { return executor.resetStepDocstringConfig; }
2171
+ });
2172
+ Object.defineProperty(exports, 'resetStepTableConfig', {
2173
+ enumerable: true,
2174
+ get: function () { return executor.resetStepTableConfig; }
2175
+ });
2176
+ Object.defineProperty(exports, 'setStepDocstring', {
2177
+ enumerable: true,
2178
+ get: function () { return executor.setStepDocstring; }
2179
+ });
2180
+ Object.defineProperty(exports, 'setStepDocstringInfo', {
2181
+ enumerable: true,
2182
+ get: function () { return executor.setStepDocstringInfo; }
2183
+ });
2184
+ Object.defineProperty(exports, 'setStepTable', {
2185
+ enumerable: true,
2186
+ get: function () { return executor.setStepTable; }
2187
+ });
2188
+ exports.App = App;
2189
+ exports.CucumberRunner = CucumberRunner;
2190
+ exports.ParameterRegistryAdapter = ParameterRegistryAdapter;
2191
+ exports.RunnerContext = RunnerContext;
2192
+ exports.STEPS_ENVIRONMENT_META = STEPS_ENVIRONMENT_META;
2193
+ exports.WORLD_INHERIT_KEYS = WORLD_INHERIT_KEYS;
2194
+ exports.WORLD_TOKEN = WORLD_TOKEN;
2195
+ exports.clearCurrentRunnerSteps = clearCurrentRunnerSteps;
2196
+ exports.configureGlobalRunner = configureGlobalRunner;
2197
+ exports.coordinateRunnerFeature = coordinateRunnerFeature;
2198
+ exports.createDecoratorRunner = createDecoratorRunner;
2199
+ exports.createGlobalRunner = createGlobalRunner;
2200
+ exports.createParameterRegistryAdapter = createParameterRegistryAdapter;
2201
+ exports.createRunner = createRunner;
2202
+ exports.default = createRunner;
2203
+ exports.disposeGlobalRunner = disposeGlobalRunner;
2204
+ exports.getConfiguredGlobalRunner = getConfiguredGlobalRunner;
2205
+ exports.getCurrentRunnerSteps = getCurrentRunnerSteps;
2206
+ exports.getGlobalRunner = getGlobalRunner;
2207
+ exports.getGlobalRunnerEnvironment = getGlobalRunnerEnvironment;
2208
+ exports.resetGlobalRunner = resetGlobalRunner;
2209
+ exports.setCurrentRunnerSteps = setCurrentRunnerSteps;
2210
+ exports.useGlobalRunnerEnvironment = useGlobalRunnerEnvironment;
2211
+ //# sourceMappingURL=out.js.map
2212
+ //# sourceMappingURL=index.cjs.map