@step-forge/step-forge 0.0.17 → 0.0.19

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.
@@ -746,6 +746,15 @@ async function resolveGlobs(patterns) {
746
746
  return [...new Set(files)];
747
747
  }
748
748
  //#endregion
749
+ //#region src/init.ts
750
+ const createBuilders = () => {
751
+ return {
752
+ Given: givenBuilder().statement,
753
+ When: whenBuilder().statement,
754
+ Then: thenBuilder().statement
755
+ };
756
+ };
757
+ //#endregion
749
758
  //#region src/index.ts
750
759
  const analyzer = {
751
760
  analyze,
@@ -760,6 +769,7 @@ const analyzer = {
760
769
  exports.BasicWorld = BasicWorld;
761
770
  exports.analyzer = analyzer;
762
771
  exports.booleanParser = booleanParser;
772
+ exports.createBuilders = createBuilders;
763
773
  exports.givenBuilder = givenBuilder;
764
774
  exports.intParser = intParser;
765
775
  exports.numberParser = numberParser;
@@ -1 +1 @@
1
- {"version":3,"file":"step-forge.cjs","names":["CucGiven","CucWhen","CucThen","_","_","ts","fs","Parser","AstBuilder","messages","GherkinClassicTokenMatcher","path"],"sources":["../../src/builderTypeUtils.ts","../../src/parsers.ts","../../src/utils.ts","../../src/common.ts","../../src/given.ts","../../src/when.ts","../../src/then.ts","../../src/world.ts","../../src/analyzer/stepExtractor.ts","../../src/analyzer/gherkinParser.ts","../../src/analyzer/stepMatcher.ts","../../src/analyzer/rules/ambiguousStepRule.ts","../../src/analyzer/rules/dependencyRule.ts","../../src/analyzer/rules/undefinedStepRule.ts","../../src/analyzer/rules/index.ts","../../src/analyzer/index.ts","../../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nexport type StepType = \"given\" | \"when\" | \"then\";\n\nexport type InferAndReplace<T, U> = never extends T ? U : T;\n\nexport type HasKeys<T> =\n T extends Record<any, any> ? (keyof T extends never ? never : T) : T;\n\nexport type EmptyObject = Record<string, never>;\n\nexport type RequiredOrOptional<T> = {\n [K in keyof T]?: \"required\" | \"optional\";\n};\n\nexport type GetFunctionArgs<T> = T extends (...args: infer A) => any\n ? A\n : never;\n\nexport const isString = (\n statement: string | ((...args: [...any]) => string)\n): statement is string => typeof statement === \"string\";\n\nexport type EmptyDependencies = {\n given: EmptyObject;\n when: EmptyObject;\n then: EmptyObject;\n};\n","/**\n * A Parser maps a Cucumber expression placeholder to a typed value.\n *\n * `gherkin` is the Cucumber Expression placeholder used when registering the\n * step (e.g. `{int}`). `parse` converts the raw value Cucumber captures into\n * the desired TypeScript type.\n *\n * Note: Cucumber Expressions already transform `{int}`/`{float}` captures into\n * JS numbers before the step function runs, so `parse` receives an `unknown`\n * and must tolerate both the pre-transformed value and a raw string.\n */\nexport type Parser<T> = {\n parse: (value: unknown) => T;\n gherkin: string;\n};\n\n/** Matches a quoted string (`{string}`) and passes the unquoted contents through. */\nexport const stringParser: Parser<string> = {\n parse: value => String(value),\n gherkin: \"{string}\",\n};\n\n/** Matches an unquoted integer (`{int}`). */\nexport const intParser: Parser<number> = {\n parse: value =>\n typeof value === \"number\" ? value : parseInt(String(value), 10),\n gherkin: \"{int}\",\n};\n\n/** Matches an unquoted floating point number (`{float}`). */\nexport const numberParser: Parser<number> = {\n parse: value =>\n typeof value === \"number\" ? value : parseFloat(String(value)),\n gherkin: \"{float}\",\n};\n\n/** Matches an unquoted `true`/`false` word (`{word}`) and parses it to a boolean. */\nexport const booleanParser: Parser<boolean> = {\n parse: value => value === true || value === \"true\",\n gherkin: \"{word}\",\n};\n","import { MergeableWorld } from \"./world\";\n\nexport const requireFromGiven = <G>(\n keys: (keyof G)[],\n world: MergeableWorld<G, unknown, unknown>\n) => {\n keys.forEach(key => {\n if (!world.given[key]) {\n throw new Error(`Key ${String(key)} is required in given state`);\n }\n });\n return keys.reduce(\n (acc, key) => {\n return {\n ...acc,\n [key]: world.given[key],\n };\n },\n {} as { [key in keyof G]: G[key] }\n );\n};\nexport const requireFromWhen = <W>(\n keys: (keyof W)[],\n world: MergeableWorld<unknown, W, unknown>\n) => {\n keys.forEach(key => {\n if (!world.when[key]) {\n throw new Error(`Key ${String(key)} is required in when state`);\n }\n });\n return keys.reduce(\n (acc, key) => {\n return {\n ...acc,\n [key]: world.when[key],\n };\n },\n {} as { [key in keyof W]: W[key] }\n );\n};\nexport const requireFromThen = <T>(\n keys: (keyof T)[],\n world: MergeableWorld<unknown, unknown, T>\n) => {\n keys.forEach(key => {\n if (!world.then[key]) {\n throw new Error(`Key ${String(key)} is required in then state`);\n }\n });\n return keys.reduce(\n (acc, key) => {\n return {\n ...acc,\n [key]: world.then[key],\n };\n },\n {} as { [key in keyof T]: T[key] }\n );\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n Given as CucGiven,\n Then as CucThen,\n When as CucWhen,\n} from \"@cucumber/cucumber\";\nimport _ from \"lodash\";\n\nimport { StepType } from \"./builderTypeUtils\";\nimport { Parser, stringParser } from \"./parsers\";\nimport { requireFromGiven, requireFromThen, requireFromWhen } from \"./utils\";\nimport { MergeableWorld } from \"./world\";\n\nconst cucFunctionMap = {\n given: CucGiven,\n when: CucWhen,\n then: CucThen,\n};\n\nexport const addStep =\n <\n ResolvedStepType extends StepType,\n Statement extends (...args: any[]) => string,\n Dependencies extends {\n given: any;\n when: any;\n then: any;\n },\n Variables,\n GivenState,\n WhenState,\n ThenState,\n RestrictedGivenState,\n RestrictedWhenState,\n RestrictedThenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n dependencies: Dependencies = {\n given: {},\n when: {},\n then: {},\n } as Dependencies,\n declaredParsers?: Parser<any>[]\n ) =>\n (\n stepFunction: (input: {\n variables: Variables;\n given: RestrictedGivenState;\n when: RestrictedWhenState;\n then: RestrictedThenState;\n }) => ResolvedStepType extends \"given\"\n ? Partial<GivenState> | Promise<Partial<GivenState>>\n : ResolvedStepType extends \"when\"\n ? Partial<WhenState> | Promise<Partial<WhenState>>\n :\n | Partial<ThenState>\n | Promise<Partial<ThenState>>\n | void\n | Promise<void>\n ) => {\n const statementFunction = statement;\n const {\n given: givenDependencies,\n when: whenDependencies,\n then: thenDependencies,\n } = dependencies;\n // Resolve the parsers up front, defaulting every variable to `stringParser`\n // (the `{string}` placeholder, value passed through unchanged) when none are\n // provided. Numeric/boolean values are opt-in via explicit parsers.\n const argCount = statementFunction.length;\n const parsers =\n declaredParsers ?? Array.from({ length: argCount }, () => stringParser);\n const expression = statementFunction(\n ...parsers.map(parser => parser.gherkin)\n );\n return {\n statement,\n expression,\n dependencies,\n stepType,\n stepFunction,\n register: () => {\n const cucStepFunction = Object.defineProperty(\n async function (\n this: MergeableWorld<GivenState, WhenState, ThenState>,\n ...args: string[]\n ) {\n // Iterate over parsers (not args) so Cucumber's trailing\n // arguments don't get parsed as if they were captured variables.\n const coercedArgs = parsers.map((parser, index) =>\n parser.parse(args[index])\n );\n const requiredGivenKeys = Object.entries(givenDependencies ?? {})\n .filter(([, value]) => value === \"required\")\n .map(([key]) => key);\n const ensuredGivenValues = requireFromGiven(\n requiredGivenKeys as (keyof GivenState)[],\n this\n );\n const narrowedGiven = {\n ..._.pick(this.given, Object.keys(givenDependencies ?? {})),\n ...ensuredGivenValues,\n };\n const requiredWhenKeys = Object.entries(whenDependencies ?? {})\n .filter(([, value]) => value === \"required\")\n .map(([key]) => key);\n const ensuredWhenValues = requireFromWhen(\n requiredWhenKeys as (keyof WhenState)[],\n this\n );\n const narrowedWhen = {\n ..._.pick(this.when, Object.keys(whenDependencies ?? {})),\n ...ensuredWhenValues,\n };\n const requiredThenKeys = Object.entries(thenDependencies ?? {})\n .filter(([, value]) => value === \"required\")\n .map(([key]) => key);\n const ensuredThenValues = requireFromThen(\n requiredThenKeys as (keyof ThenState)[],\n this\n );\n const narrowedThen = {\n ..._.pick(this.then, Object.keys(thenDependencies ?? {})),\n ...ensuredThenValues,\n };\n const result = await stepFunction({\n variables: coercedArgs as Variables,\n given: narrowedGiven as RestrictedGivenState,\n when: narrowedWhen as RestrictedWhenState,\n then: narrowedThen as RestrictedThenState,\n });\n this[stepType].merge({\n ...(result as any),\n });\n },\n \"length\",\n { value: argCount, configurable: true }\n );\n const cucStep = cucFunctionMap[stepType];\n cucStep(expression, cucStepFunction);\n return {\n stepType,\n expression,\n dependencies,\n statement: statementFunction,\n stepFunction,\n };\n },\n };\n };\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n EmptyDependencies,\n EmptyObject,\n GetFunctionArgs,\n isString,\n RequiredOrOptional,\n StepType,\n} from \"./builderTypeUtils\";\nimport { addStep } from \"./common\";\nimport { Parser } from \"./parsers\";\n\nconst givenDependencies =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables,\n GivenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n parsers?: Parser<any>[]\n ) =>\n <GivenDeps extends RequiredOrOptional<GivenState>>(dependencies: {\n given: GivenDeps;\n }) => {\n type RestrictedGivenState = {\n [K in keyof GivenState as K extends keyof GivenDeps\n ? K\n : never]: GivenDeps[K] extends \"optional\"\n ? GivenState[K] | undefined\n : GivenState[K];\n };\n type Dependencies = typeof dependencies & {\n when: EmptyObject;\n then: EmptyObject;\n };\n const fullDependencies = {\n ...dependencies,\n when: {},\n then: {},\n };\n return {\n step: addStep<\n ResolvedStepType,\n Statement,\n Dependencies,\n Variables,\n GivenState,\n never, // when state\n never, // then state\n RestrictedGivenState,\n never, // restricted when state\n never // restricted then state\n >(statement, stepType, fullDependencies, parsers),\n };\n };\n\nconst givenParsers =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables extends any[],\n GivenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType\n ) =>\n <Parsers extends { [K in keyof Variables]: Parser<Variables[K]> }>(\n parsers: Parsers\n ) => {\n return {\n dependencies: givenDependencies<\n Statement,\n ResolvedStepType,\n Variables,\n GivenState\n >(statement, stepType, parsers as unknown as Parser<any>[]),\n step: addStep<\n ResolvedStepType,\n Statement,\n EmptyDependencies,\n Variables,\n GivenState,\n never,\n never,\n never,\n never,\n never\n >(statement, stepType, undefined, parsers as unknown as Parser<any>[]),\n };\n };\n\nconst givenStatement =\n <ResolvedStepType extends StepType, GivenState>(stepType: ResolvedStepType) =>\n <Statement extends ((...args: [...any]) => string) | string>(\n statement: Statement\n ) => {\n let normalizedStatement: Statement extends string\n ? () => string\n : Statement;\n if (isString(statement)) {\n normalizedStatement = (() => statement) as any;\n } else {\n normalizedStatement = statement as any;\n }\n type NormalizedStatement = typeof normalizedStatement;\n\n type Variables = Statement extends string ? [] : GetFunctionArgs<Statement>;\n const dependencyFunc = givenDependencies<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState\n >(normalizedStatement, stepType);\n const parsersFunc = givenParsers<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState\n >(normalizedStatement, stepType);\n const stepFunc = addStep<\n ResolvedStepType,\n NormalizedStatement,\n EmptyDependencies,\n Variables,\n GivenState,\n never,\n never,\n never,\n never,\n never\n >(normalizedStatement, stepType);\n return {\n dependencies: dependencyFunc,\n parsers: parsersFunc,\n step: stepFunc,\n };\n };\n\nexport const givenBuilder = <GivenState>() => {\n return {\n statement: givenStatement<\"given\", GivenState>(\"given\"),\n };\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n EmptyDependencies,\n EmptyObject,\n GetFunctionArgs,\n isString,\n RequiredOrOptional,\n StepType,\n} from \"./builderTypeUtils\";\nimport { addStep } from \"./common\";\nimport { Parser } from \"./parsers\";\n\nconst whenDependencies =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables,\n GivenState,\n WhenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n parsers?: Parser<any>[]\n ) =>\n <\n GivenDeps extends RequiredOrOptional<GivenState>,\n WhenDeps extends RequiredOrOptional<WhenState>,\n >(dependencies: {\n given?: GivenDeps;\n when?: WhenDeps;\n }) => {\n type RestrictedGivenState = {\n [K in keyof GivenState as K extends keyof GivenDeps\n ? K\n : never]: GivenDeps[K] extends \"optional\"\n ? GivenState[K] | undefined\n : GivenState[K];\n };\n type RestrictedWhenState = {\n [K in keyof WhenState as K extends keyof WhenDeps\n ? K\n : never]: WhenDeps[K] extends \"optional\"\n ? WhenState[K] | undefined\n : WhenState[K];\n };\n type Dependencies = {\n given: GivenDeps;\n when: WhenDeps;\n then: EmptyObject;\n };\n const fullDependencies: Dependencies = {\n given: dependencies.given ?? ({} as GivenDeps),\n when: dependencies.when ?? ({} as WhenDeps),\n then: {},\n };\n return {\n step: addStep<\n ResolvedStepType,\n Statement,\n Dependencies,\n Variables,\n GivenState,\n WhenState,\n never,\n RestrictedGivenState,\n RestrictedWhenState,\n never\n >(statement, stepType, fullDependencies, parsers),\n };\n };\n\nconst whenParsers =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables extends any[],\n GivenState,\n WhenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType\n ) =>\n <Parsers extends { [K in keyof Variables]: Parser<Variables[K]> }>(\n parsers: Parsers\n ) => {\n return {\n dependencies: whenDependencies<\n Statement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState\n >(statement, stepType, parsers as unknown as Parser<any>[]),\n step: addStep<\n ResolvedStepType,\n Statement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n never,\n never,\n never,\n never\n >(statement, stepType, undefined, parsers as unknown as Parser<any>[]),\n };\n };\n\nconst whenStatement =\n <ResolvedStepType extends StepType, GivenState, WhenState>(\n stepType: ResolvedStepType\n ) =>\n <Statement extends ((...args: [...any]) => string) | string>(\n statement: Statement\n ) => {\n let normalizedStatement: Statement extends string\n ? () => string\n : Statement;\n if (isString(statement)) {\n normalizedStatement = (() => statement) as any;\n } else {\n normalizedStatement = statement as any;\n }\n type NormalizedStatement = typeof normalizedStatement;\n\n type Variables = Statement extends string ? [] : GetFunctionArgs<Statement>;\n const dependencyFunc = whenDependencies<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState\n >(normalizedStatement, stepType);\n const parsersFunc = whenParsers<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState\n >(normalizedStatement, stepType);\n const stepFunc = addStep<\n ResolvedStepType,\n NormalizedStatement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n never,\n never,\n never,\n never\n >(normalizedStatement, stepType);\n return {\n dependencies: dependencyFunc,\n parsers: parsersFunc,\n step: stepFunc,\n };\n };\n\nexport const whenBuilder = <GivenState, WhenState>() => {\n return {\n statement: whenStatement<\"when\", GivenState, WhenState>(\"when\"),\n };\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n EmptyDependencies,\n GetFunctionArgs,\n isString,\n RequiredOrOptional,\n StepType,\n} from \"./builderTypeUtils\";\nimport { addStep } from \"./common\";\nimport { Parser } from \"./parsers\";\n\nconst thenDependencies =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n parsers?: Parser<any>[]\n ) =>\n <\n GivenDeps extends RequiredOrOptional<GivenState>,\n WhenDeps extends RequiredOrOptional<WhenState>,\n ThenDeps extends RequiredOrOptional<ThenState>,\n >(dependencies: {\n given?: GivenDeps;\n when?: WhenDeps;\n then?: ThenDeps;\n }) => {\n type RestrictedGivenState = {\n [K in keyof GivenState as K extends keyof GivenDeps\n ? K\n : never]: GivenDeps[K] extends \"optional\"\n ? GivenState[K] | undefined\n : GivenState[K];\n };\n type RestrictedWhenState = {\n [K in keyof WhenState as K extends keyof WhenDeps\n ? K\n : never]: WhenDeps[K] extends \"optional\"\n ? WhenState[K] | undefined\n : WhenState[K];\n };\n type RestrictedThenState = {\n [K in keyof ThenState as K extends keyof ThenDeps\n ? K\n : never]: ThenDeps[K] extends \"optional\"\n ? ThenState[K] | undefined\n : ThenState[K];\n };\n type Dependencies = {\n given: GivenDeps;\n when: WhenDeps;\n then: ThenDeps;\n };\n const fullDependencies: Dependencies = {\n given: dependencies.given ?? ({} as GivenDeps),\n when: dependencies.when ?? ({} as WhenDeps),\n then: dependencies.then ?? ({} as ThenDeps),\n };\n return {\n step: addStep<\n ResolvedStepType,\n Statement,\n Dependencies,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n RestrictedGivenState,\n RestrictedWhenState,\n RestrictedThenState\n >(statement, stepType, fullDependencies, parsers),\n };\n };\n\nconst thenParsers =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables extends any[],\n GivenState,\n WhenState,\n ThenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType\n ) =>\n <Parsers extends { [K in keyof Variables]: Parser<Variables[K]> }>(\n parsers: Parsers\n ) => {\n return {\n dependencies: thenDependencies<\n Statement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState,\n ThenState\n >(statement, stepType, parsers as unknown as Parser<any>[]),\n step: addStep<\n ResolvedStepType,\n Statement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n never,\n never,\n never\n >(statement, stepType, undefined, parsers as unknown as Parser<any>[]),\n };\n };\n\nconst thenStatement =\n <ResolvedStepType extends StepType, GivenState, WhenState, ThenState>(\n stepType: ResolvedStepType\n ) =>\n <Statement extends ((...args: [...any]) => string) | string>(\n statement: Statement\n ) => {\n let normalizedStatement: Statement extends string\n ? () => string\n : Statement;\n if (isString(statement)) {\n normalizedStatement = (() => statement) as any;\n } else {\n normalizedStatement = statement as any;\n }\n type NormalizedStatement = typeof normalizedStatement;\n\n type Variables = Statement extends string ? [] : GetFunctionArgs<Statement>;\n const dependencyFunc = thenDependencies<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState,\n ThenState\n >(normalizedStatement, stepType);\n const parsersFunc = thenParsers<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState,\n ThenState\n >(normalizedStatement, stepType);\n const stepFunc = addStep<\n ResolvedStepType,\n NormalizedStatement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n never,\n never,\n never\n >(normalizedStatement, stepType);\n return {\n dependencies: dependencyFunc,\n parsers: parsersFunc,\n step: stepFunc,\n };\n };\n\nexport const thenBuilder = <GivenState, WhenState, ThenState>() => {\n return {\n statement: thenStatement<\"then\", GivenState, WhenState, ThenState>(\"then\"),\n };\n};\n","import _ from \"lodash\";\n\nexport type WorldState<State> = {\n readonly [K in keyof State]?: State[K];\n};\n\nexport type MergeableWorldState<T> = WorldState<T> & {\n merge: (newState: Partial<T>) => void;\n};\n\nfunction mergeCustomizer(objValue: unknown, srcValue: unknown) {\n if (_.isArray(objValue)) {\n return objValue.concat(srcValue);\n } else if (objValue && !_.isPlainObject(objValue) && objValue !== srcValue) {\n throw new Error(\n `Merge would have destroyed previous value ${objValue} with ${srcValue}`\n );\n }\n return objValue;\n}\n\nexport const createMergeableState = <T>(\n state: WorldState<T>\n): MergeableWorldState<T> => {\n return {\n ...state,\n merge: (newState: Partial<T>) => {\n state = _.merge({ ...state }, newState, mergeCustomizer);\n },\n };\n};\n\nexport type MergeableWorld<Given, When, Then> = {\n given: MergeableWorldState<Given>;\n when: MergeableWorldState<When>;\n then: MergeableWorldState<Then>;\n};\n\nexport class BasicWorld<Given, When, Then> {\n private givenState: WorldState<Given> = {};\n private whenState: WorldState<When> = {};\n private thenState: WorldState<Then> = {};\n\n public get given(): MergeableWorldState<Given> {\n return {\n ...this.givenState,\n merge: (newState: Partial<Given>) => {\n this.givenState = _.merge(\n { ...this.givenState },\n newState,\n mergeCustomizer\n );\n },\n };\n }\n\n public get when(): MergeableWorldState<When> {\n return {\n ...this.whenState,\n merge: (newState: Partial<When>) => {\n this.whenState = _.merge(\n { ...this.whenState },\n newState,\n mergeCustomizer\n );\n },\n };\n }\n\n public get then(): MergeableWorldState<Then> {\n return {\n ...this.thenState,\n merge: (newState: Partial<Then>) => {\n this.thenState = _.merge(\n { ...this.thenState },\n newState,\n mergeCustomizer\n );\n },\n };\n }\n}\n\nexport const createBasicWorld = <Given, When, Then>(): MergeableWorld<\n Given,\n When,\n Then\n> => {\n return new BasicWorld<Given, When, Then>();\n};\n","import ts from \"typescript\";\nimport { StepDefinitionMeta } from \"./types.js\";\n\ntype StepType = \"given\" | \"when\" | \"then\";\n\nconst BUILDER_NAMES: Record<string, StepType> = {\n givenBuilder: \"given\",\n whenBuilder: \"when\",\n thenBuilder: \"then\",\n};\n\nexport function extractStepDefinitions(\n filePaths: string[],\n tsConfigPath?: string\n): StepDefinitionMeta[] {\n const configPath =\n tsConfigPath ?? ts.findConfigFile(process.cwd(), ts.sys.fileExists);\n let compilerOptions: ts.CompilerOptions = {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Node10,\n strict: true,\n esModuleInterop: true,\n };\n\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (!configFile.error) {\n const parsed = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n configPath.replace(/[/\\\\][^/\\\\]+$/, \"\")\n );\n compilerOptions = parsed.options;\n }\n }\n\n // Ensure noEmit so we don't write files\n compilerOptions.noEmit = true;\n\n const program = ts.createProgram(filePaths, compilerOptions);\n const checker = program.getTypeChecker();\n const results: StepDefinitionMeta[] = [];\n\n for (const filePath of filePaths) {\n const sourceFile = program.getSourceFile(filePath);\n if (!sourceFile) continue;\n const fileResults = extractFromSourceFile(sourceFile, checker);\n results.push(...fileResults);\n }\n\n return results;\n}\n\nfunction extractFromSourceFile(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker\n): StepDefinitionMeta[] {\n const results: StepDefinitionMeta[] = [];\n\n function visit(node: ts.Node) {\n // Look for .register() call expressions\n if (\n ts.isCallExpression(node) &&\n ts.isPropertyAccessExpression(node.expression) &&\n node.expression.name.text === \"register\"\n ) {\n const meta = extractFromRegisterCall(node, sourceFile, checker);\n if (meta) {\n results.push(meta);\n }\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return results;\n}\n\nfunction extractFromRegisterCall(\n registerCall: ts.CallExpression,\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker\n): StepDefinitionMeta | null {\n // Walk backwards through the method chain to find all parts\n // Pattern: builder().statement(...).dependencies?(...).step(...).register()\n // Or: Variable(\"...\").dependencies?(...).step(...).register()\n\n const chain = collectCallChain(registerCall);\n\n let stepType: StepType | null = null;\n let expression: string | null = null;\n let dependencies: StepDefinitionMeta[\"dependencies\"] = {\n given: {},\n when: {},\n then: {},\n };\n let produces: string[] = [];\n\n for (const link of chain) {\n const name = getCallName(link);\n if (!name) continue;\n\n if (name === \"register\") {\n // Already at register, continue\n continue;\n }\n\n if (name === \"step\") {\n produces = extractProducedKeys(link, checker);\n continue;\n }\n\n if (name === \"dependencies\") {\n dependencies = extractDependencies(link);\n continue;\n }\n\n if (name === \"statement\") {\n expression = extractExpression(link);\n // Try to find the builder type by continuing up the chain\n continue;\n }\n\n // Check if this is a builder call like givenBuilder()\n if (BUILDER_NAMES[name]) {\n stepType = BUILDER_NAMES[name];\n continue;\n }\n }\n\n // If we didn't find the builder or expression in the chain, try the \"re-exported\" pattern:\n // const Given = givenBuilder<T>().statement;\n // Given(\"foo\").step(...).register()\n if (!stepType || !expression) {\n const reExport = resolveReExportedCall(chain, checker);\n if (reExport) {\n if (!stepType) stepType = reExport.stepType;\n if (!expression) expression = reExport.expression;\n }\n }\n\n if (!stepType || !expression) {\n return null;\n }\n\n const line =\n sourceFile.getLineAndCharacterOfPosition(registerCall.getStart()).line + 1;\n\n return {\n stepType,\n expression,\n dependencies,\n produces,\n sourceFile: sourceFile.fileName,\n line,\n };\n}\n\n/**\n * Collect all call expressions in the method chain, from register() back to the origin.\n */\nfunction collectCallChain(call: ts.CallExpression): ts.CallExpression[] {\n const chain: ts.CallExpression[] = [call];\n let current: ts.Expression = call.expression;\n\n while (true) {\n // Walk through PropertyAccessExpression to find the next call\n if (ts.isPropertyAccessExpression(current)) {\n current = current.expression;\n }\n\n if (ts.isCallExpression(current)) {\n chain.push(current);\n current = current.expression;\n } else {\n break;\n }\n }\n\n return chain;\n}\n\nfunction getCallName(call: ts.CallExpression): string | null {\n const expr = call.expression;\n\n // .method() pattern\n if (ts.isPropertyAccessExpression(expr)) {\n return expr.name.text;\n }\n\n // direct call: functionName()\n if (ts.isIdentifier(expr)) {\n return expr.text;\n }\n\n return null;\n}\n\nfunction extractExpression(statementCall: ts.CallExpression): string | null {\n const arg = statementCall.arguments[0];\n if (!arg) return null;\n\n // String literal: .statement(\"a user\")\n if (ts.isStringLiteral(arg)) {\n return arg.text;\n }\n\n // Arrow function with template literal: .statement((name: string) => `a user named ${name}`)\n if (ts.isArrowFunction(arg)) {\n return extractExpressionFromArrowFunction(arg);\n }\n\n return null;\n}\n\nfunction extractExpressionFromArrowFunction(\n fn: ts.ArrowFunction\n): string | null {\n const params = fn.parameters.map((p) => p.name.getText());\n\n // The body should be a template expression or string literal\n let body = fn.body;\n\n // If wrapped in a block with a return, unwrap\n if (ts.isBlock(body)) {\n const returnStmt = body.statements.find(ts.isReturnStatement);\n if (returnStmt?.expression) {\n body = returnStmt.expression;\n } else {\n return null;\n }\n }\n\n if (ts.isTemplateExpression(body)) {\n return reconstructExpressionFromTemplate(body, params);\n }\n\n if (ts.isNoSubstitutionTemplateLiteral(body)) {\n return body.text;\n }\n\n return null;\n}\n\nfunction reconstructExpressionFromTemplate(\n template: ts.TemplateExpression,\n paramNames: string[]\n): string {\n let result = template.head.text;\n\n for (const span of template.templateSpans) {\n if (ts.isIdentifier(span.expression) && paramNames.includes(span.expression.text)) {\n result += \"{string}\";\n } else {\n // Non-parameter expression, use {string} as fallback\n result += \"{string}\";\n }\n result += span.literal.text;\n }\n\n return result;\n}\n\nfunction extractDependencies(\n depsCall: ts.CallExpression\n): StepDefinitionMeta[\"dependencies\"] {\n const deps: StepDefinitionMeta[\"dependencies\"] = {\n given: {},\n when: {},\n then: {},\n };\n\n const arg = depsCall.arguments[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) return deps;\n\n for (const prop of arg.properties) {\n if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name))\n continue;\n\n const phase = prop.name.text as \"given\" | \"when\" | \"then\";\n if (!deps[phase]) continue;\n\n if (ts.isObjectLiteralExpression(prop.initializer)) {\n for (const innerProp of prop.initializer.properties) {\n if (\n ts.isPropertyAssignment(innerProp) &&\n ts.isIdentifier(innerProp.name) &&\n ts.isStringLiteral(innerProp.initializer)\n ) {\n const val = innerProp.initializer.text;\n if (val === \"required\" || val === \"optional\") {\n deps[phase][innerProp.name.text] = val;\n }\n }\n }\n }\n }\n\n return deps;\n}\n\nfunction extractProducedKeys(\n stepCall: ts.CallExpression,\n checker: ts.TypeChecker\n): string[] {\n const callback = stepCall.arguments[0];\n if (!callback) return [];\n\n // Try to get the return type of the callback by analyzing its body\n if (ts.isArrowFunction(callback) || ts.isFunctionExpression(callback)) {\n return extractProducedKeysFromCallback(callback, checker);\n }\n\n return [];\n}\n\nfunction extractProducedKeysFromCallback(\n callback: ts.ArrowFunction | ts.FunctionExpression,\n checker: ts.TypeChecker\n): string[] {\n const body = callback.body;\n\n // Concise arrow: () => ({ key: value })\n if (!ts.isBlock(body)) {\n return extractKeysFromExpression(body, checker);\n }\n\n // Block body: look at return statements\n const keys = new Set<string>();\n function visitReturn(node: ts.Node) {\n if (ts.isReturnStatement(node) && node.expression) {\n for (const key of extractKeysFromExpression(node.expression, checker)) {\n keys.add(key);\n }\n }\n ts.forEachChild(node, visitReturn);\n }\n visitReturn(body);\n return [...keys];\n}\n\nfunction extractKeysFromExpression(\n expr: ts.Expression,\n checker: ts.TypeChecker\n): string[] {\n // Unwrap parenthesized expressions\n while (ts.isParenthesizedExpression(expr)) {\n expr = expr.expression;\n }\n\n // Object literal: { user: ..., token: ... }\n if (ts.isObjectLiteralExpression(expr)) {\n return expr.properties\n .filter(\n (p): p is ts.PropertyAssignment | ts.ShorthandPropertyAssignment =>\n ts.isPropertyAssignment(p) || ts.isShorthandPropertyAssignment(p)\n )\n .map((p) => p.name.getText())\n .filter(Boolean);\n }\n\n // Try type checker as fallback\n try {\n const type = checker.getTypeAtLocation(expr);\n return type\n .getProperties()\n .map((p) => p.name)\n .filter((n) => n !== \"merge\");\n } catch {\n return [];\n }\n}\n\ninterface ReExportResult {\n stepType: StepType;\n expression: string | null;\n}\n\nfunction resolveReExportedCall(\n chain: ts.CallExpression[],\n checker: ts.TypeChecker\n): ReExportResult | null {\n // Look for the pattern: Variable(\"...\")... where Variable was assigned from builderType().statement\n // The last call in the chain (furthest from register) should be the variable call\n\n const lastCall = chain[chain.length - 1];\n if (!lastCall) return null;\n\n const expr = lastCall.expression;\n\n // If it's an identifier (like \"Given\", \"When\", \"Then\"), trace its declaration\n let identifier: ts.Identifier | null = null;\n if (ts.isIdentifier(expr)) {\n identifier = expr;\n } else if (\n ts.isPropertyAccessExpression(expr) &&\n ts.isIdentifier(expr.expression)\n ) {\n identifier = expr.expression;\n }\n\n if (!identifier) return null;\n\n const symbol = checker.getSymbolAtLocation(identifier);\n if (!symbol) return null;\n\n const decl = symbol.valueDeclaration;\n if (!decl || !ts.isVariableDeclaration(decl) || !decl.initializer)\n return null;\n\n // Check if initializer is builderType<T>().statement\n const init = decl.initializer;\n\n // Pattern: givenBuilder<T>().statement (PropertyAccessExpression)\n if (ts.isPropertyAccessExpression(init) && init.name.text === \"statement\") {\n const callExpr = init.expression;\n if (ts.isCallExpression(callExpr)) {\n const callee = callExpr.expression;\n if (ts.isIdentifier(callee) && BUILDER_NAMES[callee.text]) {\n // The lastCall IS the statement call — extract expression from it\n const expression = extractExpression(lastCall);\n return {\n stepType: BUILDER_NAMES[callee.text],\n expression,\n };\n }\n }\n }\n\n return null;\n}\n","import * as fs from \"node:fs\";\nimport { GherkinClassicTokenMatcher, Parser, AstBuilder } from \"@cucumber/gherkin\";\nimport * as messages from \"@cucumber/messages\";\nimport { ParsedScenario, ParsedStep } from \"./types.js\";\n\ntype GherkinKeyword = \"Given\" | \"When\" | \"Then\" | \"And\" | \"But\";\n\nexport function parseFeatureFiles(filePaths: string[]): ParsedScenario[] {\n const scenarios: ParsedScenario[] = [];\n\n for (const filePath of filePaths) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const parsed = parseFeatureContent(content, filePath);\n scenarios.push(...parsed);\n }\n\n return scenarios;\n}\n\nexport function parseFeatureContent(\n content: string,\n filePath: string\n): ParsedScenario[] {\n const newId = messages.IdGenerator.uuid();\n const builder = new AstBuilder(newId);\n const matcher = new GherkinClassicTokenMatcher();\n const parser = new Parser(builder, matcher);\n\n const gherkinDocument: messages.GherkinDocument = parser.parse(content);\n const feature = gherkinDocument.feature;\n if (!feature) return [];\n\n // Collect background steps at the feature level\n const featureBackground: messages.Step[] = [];\n const scenarios: ParsedScenario[] = [];\n\n for (const child of feature.children) {\n if (child.background) {\n featureBackground.push(...child.background.steps);\n }\n\n if (child.scenario) {\n scenarios.push(\n ...expandScenario(child.scenario, featureBackground, filePath)\n );\n }\n\n if (child.rule) {\n // Rules can have their own backgrounds\n const ruleBackground: messages.Step[] = [...featureBackground];\n for (const ruleChild of child.rule.children) {\n if (ruleChild.background) {\n ruleBackground.push(...ruleChild.background.steps);\n }\n if (ruleChild.scenario) {\n scenarios.push(\n ...expandScenario(ruleChild.scenario, ruleBackground, filePath)\n );\n }\n }\n }\n }\n\n return scenarios;\n}\n\nfunction expandScenario(\n scenario: messages.Scenario,\n backgroundSteps: messages.Step[],\n filePath: string\n): ParsedScenario[] {\n const hasExamples =\n scenario.examples.length > 0 &&\n scenario.examples.some((e) => e.tableBody.length > 0);\n\n if (!hasExamples) {\n // Regular scenario\n const bgParsed = convertSteps(backgroundSteps);\n const scenarioParsed = convertSteps(scenario.steps);\n const allSteps = resolveEffectiveKeywords([...bgParsed, ...scenarioParsed]);\n\n return [\n {\n name: scenario.name,\n file: filePath,\n steps: allSteps,\n },\n ];\n }\n\n // Scenario Outline — expand with each example row\n const results: ParsedScenario[] = [];\n for (const example of scenario.examples) {\n if (!example.tableHeader || example.tableBody.length === 0) continue;\n const headers = example.tableHeader.cells.map((c) => c.value);\n\n for (const row of example.tableBody) {\n const values = row.cells.map((c) => c.value);\n const substitution: Record<string, string> = {};\n headers.forEach((h, i) => {\n substitution[h] = values[i];\n });\n\n const bgParsed = convertSteps(backgroundSteps);\n const scenarioSteps = convertSteps(scenario.steps).map((step) => ({\n ...step,\n text: substituteExampleValues(step.text, substitution),\n }));\n const allSteps = resolveEffectiveKeywords([...bgParsed, ...scenarioSteps]);\n\n results.push({\n name: `${scenario.name} (${values.join(\", \")})`,\n file: filePath,\n steps: allSteps,\n });\n }\n }\n\n return results;\n}\n\nfunction convertSteps(\n steps: readonly messages.Step[]\n): Omit<ParsedStep, \"effectiveKeyword\">[] {\n return steps.map((step) => ({\n keyword: normalizeKeyword(step.keyword),\n text: step.text,\n line: step.location.line,\n // step.location.column points to the keyword start; shift past the\n // keyword (which includes a trailing space) so column points to the\n // start of the step text. This makes `column + text.length` produce\n // the correct end position for diagnostic ranges.\n column: (step.location.column ?? 1) + step.keyword.length,\n }));\n}\n\nfunction normalizeKeyword(keyword: string): GherkinKeyword {\n const trimmed = keyword.trim();\n // Gherkin keywords may include trailing space, e.g. \"Given \"\n if (trimmed === \"Given\") return \"Given\";\n if (trimmed === \"When\") return \"When\";\n if (trimmed === \"Then\") return \"Then\";\n if (trimmed === \"And\") return \"And\";\n if (trimmed === \"But\") return \"But\";\n // Fallback: treat as Given (shouldn't happen with valid Gherkin)\n return \"Given\";\n}\n\nfunction resolveEffectiveKeywords(\n steps: Omit<ParsedStep, \"effectiveKeyword\">[]\n): ParsedStep[] {\n let lastEffective: \"Given\" | \"When\" | \"Then\" = \"Given\";\n\n return steps.map((step) => {\n let effectiveKeyword: \"Given\" | \"When\" | \"Then\";\n if (step.keyword === \"And\" || step.keyword === \"But\") {\n effectiveKeyword = lastEffective;\n } else {\n effectiveKeyword = step.keyword as \"Given\" | \"When\" | \"Then\";\n }\n lastEffective = effectiveKeyword;\n\n return {\n ...step,\n effectiveKeyword,\n };\n });\n}\n\nfunction substituteExampleValues(\n text: string,\n substitution: Record<string, string>\n): string {\n let result = text;\n for (const [key, value] of Object.entries(substitution)) {\n result = result.replace(new RegExp(`<${key}>`, \"g\"), value);\n }\n return result;\n}\n","import { MatchedStep, ParsedScenario, StepDefinitionMeta } from \"./types.js\";\n\ninterface CompiledPattern {\n regex: RegExp;\n definition: StepDefinitionMeta;\n}\n\nfunction compileDefinitions(\n definitions: StepDefinitionMeta[]\n): CompiledPattern[] {\n const compiled: CompiledPattern[] = [];\n for (const def of definitions) {\n try {\n // Replace {paramType} placeholders with (.+) to match any value,\n // regardless of which parser placeholder ({string}, {int}, ...) the\n // step definition declared.\n const placeholder = \"###PLACEHOLDER###\";\n const regexStr = def.expression\n .replace(/\\{[^}]+\\}/g, placeholder)\n .replace(/[.*+?^$()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(new RegExp(placeholder, \"g\"), \"(.+)\");\n compiled.push({\n regex: new RegExp(`^${regexStr}$`, \"i\"),\n definition: def,\n });\n } catch {\n // Skip definitions with invalid expressions\n }\n }\n return compiled;\n}\n\nexport function matchScenarioSteps(\n scenario: ParsedScenario,\n definitions: StepDefinitionMeta[]\n): MatchedStep[] {\n const compiled = compileDefinitions(definitions);\n\n return scenario.steps.map(step => {\n const matches = findMatches(step.text, step.effectiveKeyword, compiled);\n return {\n ...step,\n definitions: matches,\n };\n });\n}\n\nexport function findMatchingDefinitions(\n text: string,\n effectiveKeyword: \"Given\" | \"When\" | \"Then\",\n definitions: StepDefinitionMeta[]\n): StepDefinitionMeta[] {\n const compiled = compileDefinitions(definitions);\n return findMatches(text, effectiveKeyword, compiled);\n}\n\nfunction findMatches(\n text: string,\n effectiveKeyword: \"Given\" | \"When\" | \"Then\",\n compiled: CompiledPattern[]\n): StepDefinitionMeta[] {\n const keywordToStepType: Record<string, string> = {\n Given: \"given\",\n When: \"when\",\n Then: \"then\",\n };\n const expectedStepType = keywordToStepType[effectiveKeyword];\n\n // First try to match with the correct step type\n const typedMatches: StepDefinitionMeta[] = [];\n for (const { regex, definition } of compiled) {\n if (definition.stepType !== expectedStepType) continue;\n if (regex.test(text)) typedMatches.push(definition);\n }\n\n if (typedMatches.length > 0) return typedMatches;\n\n // Fallback: match any step type\n const fallbackMatches: StepDefinitionMeta[] = [];\n for (const { regex, definition } of compiled) {\n if (regex.test(text)) fallbackMatches.push(definition);\n }\n\n return fallbackMatches;\n}\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\n\nexport const ambiguousStepRule: AnalysisRule = {\n name: \"ambiguous-step\",\n\n check(\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n ): Diagnostic[] {\n return matchedSteps\n .filter((step) => step.definitions.length > 1)\n .map((step) => {\n const locations = step.definitions\n .map((d) => `${d.sourceFile}:${d.line}`)\n .join(\", \");\n return {\n file: scenario.file,\n range: {\n startLine: step.line,\n startColumn: step.column,\n endLine: step.line,\n endColumn: step.column + step.text.length,\n },\n severity: \"error\" as const,\n message: `Step \"${step.text}\" matches multiple step definitions: ${locations}`,\n rule: \"ambiguous-step\",\n source: \"step-forge\" as const,\n };\n });\n },\n};\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\n\nexport const dependencyRule: AnalysisRule = {\n name: \"dependency-check\",\n\n check(\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n ): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const produced = {\n given: new Set<string>(),\n when: new Set<string>(),\n then: new Set<string>(),\n };\n\n for (const step of matchedSteps) {\n if (step.definitions.length !== 1) continue;\n\n const { dependencies, produces, stepType } = step.definitions[0];\n\n // Collect all missing required dependencies for this step\n const missing: Record<string, string[]> = {};\n for (const phase of [\"given\", \"when\", \"then\"] as const) {\n for (const [key, requirement] of Object.entries(dependencies[phase])) {\n if (requirement === \"required\" && !produced[phase].has(key)) {\n if (!missing[phase]) {\n missing[phase] = [];\n }\n missing[phase].push(key);\n }\n }\n }\n\n if (Object.keys(missing).length > 0) {\n const lines = Object.entries(missing).map(\n ([phase, keys]) =>\n `${phase.charAt(0).toUpperCase() + phase.slice(1)}: ${keys.map((k) => `${phase}.${k}`).join(\", \")}`\n );\n const message =\n \"Missing required dependencies:\\n\" + lines.join(\"\\n\");\n\n diagnostics.push({\n file: scenario.file,\n range: {\n startLine: step.line,\n startColumn: step.column,\n endLine: step.line,\n endColumn: step.column + step.text.length,\n },\n severity: \"error\",\n message,\n rule: \"dependency-check\",\n source: \"step-forge\",\n });\n }\n\n // Add produced keys for this step\n for (const key of produces) {\n produced[stepType].add(key);\n }\n }\n\n return diagnostics;\n },\n};\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\n\nexport const undefinedStepRule: AnalysisRule = {\n name: \"undefined-step\",\n\n check(\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n ): Diagnostic[] {\n return matchedSteps\n .filter((step) => step.definitions.length === 0)\n .map((step) => ({\n file: scenario.file,\n range: {\n startLine: step.line,\n startColumn: step.column,\n endLine: step.line,\n endColumn: step.column + step.text.length,\n },\n severity: \"error\" as const,\n message: `Step \"${step.text}\" does not match any step definition`,\n rule: \"undefined-step\",\n source: \"step-forge\" as const,\n }));\n },\n};\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\nimport { ambiguousStepRule } from \"./ambiguousStepRule.js\";\nimport { dependencyRule } from \"./dependencyRule.js\";\nimport { undefinedStepRule } from \"./undefinedStepRule.js\";\n\nexport const defaultRules: AnalysisRule[] = [\n undefinedStepRule,\n ambiguousStepRule,\n dependencyRule,\n];\n\nexport function runRules(\n rules: AnalysisRule[],\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n): Diagnostic[] {\n return rules.flatMap((rule) => rule.check(scenario, matchedSteps));\n}\n","import { glob } from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { extractStepDefinitions } from \"./stepExtractor.js\";\nimport { parseFeatureFiles, parseFeatureContent } from \"./gherkinParser.js\";\nimport {\n matchScenarioSteps,\n findMatchingDefinitions,\n} from \"./stepMatcher.js\";\nimport { defaultRules, runRules } from \"./rules/index.js\";\nimport type {\n AnalyzerConfig,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n MatchedStep,\n ParsedStep,\n} from \"./types.js\";\n\nexport type {\n AnalyzerConfig,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n MatchedStep,\n ParsedStep,\n};\n\nexport {\n extractStepDefinitions,\n parseFeatureFiles,\n parseFeatureContent,\n matchScenarioSteps,\n findMatchingDefinitions,\n defaultRules,\n};\n\nexport interface AnalyzeOptions {\n rules?: AnalysisRule[];\n}\n\nexport async function analyze(\n config: AnalyzerConfig,\n options?: AnalyzeOptions\n): Promise<Diagnostic[]> {\n const rules = options?.rules ?? defaultRules;\n\n // 1. Resolve file globs to paths\n const stepFilePaths = await resolveGlobs(config.stepFiles);\n const featureFilePaths = await resolveGlobs(config.featureFiles);\n\n if (stepFilePaths.length === 0) {\n return [];\n }\n if (featureFilePaths.length === 0) {\n return [];\n }\n\n // 2. Extract step metadata from step files\n const stepDefinitions = extractStepDefinitions(\n stepFilePaths,\n config.tsConfigPath\n );\n\n // 3. Parse feature files\n const scenarios = parseFeatureFiles(featureFilePaths);\n\n // 4. For each scenario, match steps and run rules\n const diagnostics: Diagnostic[] = [];\n for (const scenario of scenarios) {\n const matchedSteps = matchScenarioSteps(scenario, stepDefinitions);\n const scenarioDiags = runRules(rules, scenario, matchedSteps);\n diagnostics.push(...scenarioDiags);\n }\n\n return diagnostics;\n}\n\nasync function resolveGlobs(patterns: string[]): Promise<string[]> {\n const files: string[] = [];\n for (const pattern of patterns) {\n for await (const file of glob(pattern)) {\n files.push(path.resolve(file));\n }\n }\n // Deduplicate\n return [...new Set(files)];\n}\n","import { givenBuilder } from \"./given\";\nimport { whenBuilder } from \"./when\";\nimport { thenBuilder } from \"./then\";\nimport { BasicWorld } from \"./world\";\nimport {\n stringParser,\n intParser,\n numberParser,\n booleanParser,\n} from \"./parsers\";\nimport type { Parser } from \"./parsers\";\nimport {\n analyze,\n extractStepDefinitions,\n parseFeatureFiles,\n parseFeatureContent,\n matchScenarioSteps,\n findMatchingDefinitions,\n defaultRules,\n} from \"./analyzer/index\";\nimport type {\n AnalyzerConfig,\n AnalyzeOptions,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n ParsedStep,\n MatchedStep,\n} from \"./analyzer/index\";\n\nexport {\n givenBuilder,\n whenBuilder,\n thenBuilder,\n BasicWorld,\n stringParser,\n intParser,\n numberParser,\n booleanParser,\n};\n\nexport type { Parser };\nexport type { StateFromDependencies } from \"./typeHelpers\";\n\nexport const analyzer = {\n analyze,\n extractStepDefinitions,\n parseFeatureFiles,\n parseFeatureContent,\n matchScenarioSteps,\n findMatchingDefinitions,\n defaultRules,\n};\n\nexport type {\n AnalyzerConfig,\n AnalyzeOptions,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n ParsedStep,\n MatchedStep,\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"step-forge.cjs","names":["CucGiven","CucWhen","CucThen","_","_","ts","fs","Parser","AstBuilder","messages","GherkinClassicTokenMatcher","path"],"sources":["../../src/builderTypeUtils.ts","../../src/parsers.ts","../../src/utils.ts","../../src/common.ts","../../src/given.ts","../../src/when.ts","../../src/then.ts","../../src/world.ts","../../src/analyzer/stepExtractor.ts","../../src/analyzer/gherkinParser.ts","../../src/analyzer/stepMatcher.ts","../../src/analyzer/rules/ambiguousStepRule.ts","../../src/analyzer/rules/dependencyRule.ts","../../src/analyzer/rules/undefinedStepRule.ts","../../src/analyzer/rules/index.ts","../../src/analyzer/index.ts","../../src/init.ts","../../src/index.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-explicit-any */\nexport type StepType = \"given\" | \"when\" | \"then\";\n\nexport type InferAndReplace<T, U> = never extends T ? U : T;\n\nexport type HasKeys<T> =\n T extends Record<any, any> ? (keyof T extends never ? never : T) : T;\n\nexport type EmptyObject = Record<string, never>;\n\nexport type RequiredOrOptional<T> = {\n [K in keyof T]?: \"required\" | \"optional\";\n};\n\nexport type GetFunctionArgs<T> = T extends (...args: infer A) => any\n ? A\n : never;\n\nexport const isString = (\n statement: string | ((...args: [...any]) => string)\n): statement is string => typeof statement === \"string\";\n\nexport type EmptyDependencies = {\n given: EmptyObject;\n when: EmptyObject;\n then: EmptyObject;\n};\n","/**\n * A Parser maps a Cucumber expression placeholder to a typed value.\n *\n * `gherkin` is the Cucumber Expression placeholder used when registering the\n * step (e.g. `{int}`). `parse` converts the raw value Cucumber captures into\n * the desired TypeScript type.\n *\n * Note: Cucumber Expressions already transform `{int}`/`{float}` captures into\n * JS numbers before the step function runs, so `parse` receives an `unknown`\n * and must tolerate both the pre-transformed value and a raw string.\n */\nexport type Parser<T> = {\n parse: (value: unknown) => T;\n gherkin: string;\n};\n\n/** Matches a quoted string (`{string}`) and passes the unquoted contents through. */\nexport const stringParser: Parser<string> = {\n parse: value => String(value),\n gherkin: \"{string}\",\n};\n\n/** Matches an unquoted integer (`{int}`). */\nexport const intParser: Parser<number> = {\n parse: value =>\n typeof value === \"number\" ? value : parseInt(String(value), 10),\n gherkin: \"{int}\",\n};\n\n/** Matches an unquoted floating point number (`{float}`). */\nexport const numberParser: Parser<number> = {\n parse: value =>\n typeof value === \"number\" ? value : parseFloat(String(value)),\n gherkin: \"{float}\",\n};\n\n/** Matches an unquoted `true`/`false` word (`{word}`) and parses it to a boolean. */\nexport const booleanParser: Parser<boolean> = {\n parse: value => value === true || value === \"true\",\n gherkin: \"{word}\",\n};\n","import { MergeableWorld } from \"./world\";\n\nexport const requireFromGiven = <G>(\n keys: (keyof G)[],\n world: MergeableWorld<G, unknown, unknown>\n) => {\n keys.forEach(key => {\n if (!world.given[key]) {\n throw new Error(`Key ${String(key)} is required in given state`);\n }\n });\n return keys.reduce(\n (acc, key) => {\n return {\n ...acc,\n [key]: world.given[key],\n };\n },\n {} as { [key in keyof G]: G[key] }\n );\n};\nexport const requireFromWhen = <W>(\n keys: (keyof W)[],\n world: MergeableWorld<unknown, W, unknown>\n) => {\n keys.forEach(key => {\n if (!world.when[key]) {\n throw new Error(`Key ${String(key)} is required in when state`);\n }\n });\n return keys.reduce(\n (acc, key) => {\n return {\n ...acc,\n [key]: world.when[key],\n };\n },\n {} as { [key in keyof W]: W[key] }\n );\n};\nexport const requireFromThen = <T>(\n keys: (keyof T)[],\n world: MergeableWorld<unknown, unknown, T>\n) => {\n keys.forEach(key => {\n if (!world.then[key]) {\n throw new Error(`Key ${String(key)} is required in then state`);\n }\n });\n return keys.reduce(\n (acc, key) => {\n return {\n ...acc,\n [key]: world.then[key],\n };\n },\n {} as { [key in keyof T]: T[key] }\n );\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n Given as CucGiven,\n Then as CucThen,\n When as CucWhen,\n} from \"@cucumber/cucumber\";\nimport _ from \"lodash\";\n\nimport { StepType } from \"./builderTypeUtils\";\nimport { Parser, stringParser } from \"./parsers\";\nimport { requireFromGiven, requireFromThen, requireFromWhen } from \"./utils\";\nimport { MergeableWorld } from \"./world\";\n\nconst cucFunctionMap = {\n given: CucGiven,\n when: CucWhen,\n then: CucThen,\n};\n\nexport const addStep =\n <\n ResolvedStepType extends StepType,\n Statement extends (...args: any[]) => string,\n Dependencies extends {\n given: any;\n when: any;\n then: any;\n },\n Variables,\n GivenState,\n WhenState,\n ThenState,\n RestrictedGivenState,\n RestrictedWhenState,\n RestrictedThenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n dependencies: Dependencies = {\n given: {},\n when: {},\n then: {},\n } as Dependencies,\n declaredParsers?: Parser<any>[]\n ) =>\n (\n stepFunction: (input: {\n variables: Variables;\n given: RestrictedGivenState;\n when: RestrictedWhenState;\n then: RestrictedThenState;\n }) => ResolvedStepType extends \"given\"\n ? Partial<GivenState> | Promise<Partial<GivenState>>\n : ResolvedStepType extends \"when\"\n ? Partial<WhenState> | Promise<Partial<WhenState>>\n :\n | Partial<ThenState>\n | Promise<Partial<ThenState>>\n | void\n | Promise<void>\n ) => {\n const statementFunction = statement;\n const {\n given: givenDependencies,\n when: whenDependencies,\n then: thenDependencies,\n } = dependencies;\n // Resolve the parsers up front, defaulting every variable to `stringParser`\n // (the `{string}` placeholder, value passed through unchanged) when none are\n // provided. Numeric/boolean values are opt-in via explicit parsers.\n const argCount = statementFunction.length;\n const parsers =\n declaredParsers ?? Array.from({ length: argCount }, () => stringParser);\n const expression = statementFunction(\n ...parsers.map(parser => parser.gherkin)\n );\n return {\n statement,\n expression,\n dependencies,\n stepType,\n stepFunction,\n register: () => {\n const cucStepFunction = Object.defineProperty(\n async function (\n this: MergeableWorld<GivenState, WhenState, ThenState>,\n ...args: string[]\n ) {\n // Iterate over parsers (not args) so Cucumber's trailing\n // arguments don't get parsed as if they were captured variables.\n const coercedArgs = parsers.map((parser, index) =>\n parser.parse(args[index])\n );\n const requiredGivenKeys = Object.entries(givenDependencies ?? {})\n .filter(([, value]) => value === \"required\")\n .map(([key]) => key);\n const ensuredGivenValues = requireFromGiven(\n requiredGivenKeys as (keyof GivenState)[],\n this\n );\n const narrowedGiven = {\n ..._.pick(this.given, Object.keys(givenDependencies ?? {})),\n ...ensuredGivenValues,\n };\n const requiredWhenKeys = Object.entries(whenDependencies ?? {})\n .filter(([, value]) => value === \"required\")\n .map(([key]) => key);\n const ensuredWhenValues = requireFromWhen(\n requiredWhenKeys as (keyof WhenState)[],\n this\n );\n const narrowedWhen = {\n ..._.pick(this.when, Object.keys(whenDependencies ?? {})),\n ...ensuredWhenValues,\n };\n const requiredThenKeys = Object.entries(thenDependencies ?? {})\n .filter(([, value]) => value === \"required\")\n .map(([key]) => key);\n const ensuredThenValues = requireFromThen(\n requiredThenKeys as (keyof ThenState)[],\n this\n );\n const narrowedThen = {\n ..._.pick(this.then, Object.keys(thenDependencies ?? {})),\n ...ensuredThenValues,\n };\n const result = await stepFunction({\n variables: coercedArgs as Variables,\n given: narrowedGiven as RestrictedGivenState,\n when: narrowedWhen as RestrictedWhenState,\n then: narrowedThen as RestrictedThenState,\n });\n this[stepType].merge({\n ...(result as any),\n });\n },\n \"length\",\n { value: argCount, configurable: true }\n );\n const cucStep = cucFunctionMap[stepType];\n cucStep(expression, cucStepFunction);\n return {\n stepType,\n expression,\n dependencies,\n statement: statementFunction,\n stepFunction,\n };\n },\n };\n };\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n EmptyDependencies,\n EmptyObject,\n GetFunctionArgs,\n isString,\n RequiredOrOptional,\n StepType,\n} from \"./builderTypeUtils\";\nimport { addStep } from \"./common\";\nimport { Parser } from \"./parsers\";\n\nconst givenDependencies =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables,\n GivenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n parsers?: Parser<any>[]\n ) =>\n <GivenDeps extends RequiredOrOptional<GivenState>>(dependencies: {\n given: GivenDeps;\n }) => {\n type RestrictedGivenState = {\n [K in keyof GivenState as K extends keyof GivenDeps\n ? K\n : never]: GivenDeps[K] extends \"optional\"\n ? GivenState[K] | undefined\n : GivenState[K];\n };\n type Dependencies = typeof dependencies & {\n when: EmptyObject;\n then: EmptyObject;\n };\n const fullDependencies = {\n ...dependencies,\n when: {},\n then: {},\n };\n return {\n step: addStep<\n ResolvedStepType,\n Statement,\n Dependencies,\n Variables,\n GivenState,\n never, // when state\n never, // then state\n RestrictedGivenState,\n never, // restricted when state\n never // restricted then state\n >(statement, stepType, fullDependencies, parsers),\n };\n };\n\nconst givenParsers =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables extends any[],\n GivenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType\n ) =>\n <Parsers extends { [K in keyof Variables]: Parser<Variables[K]> }>(\n parsers: Parsers\n ) => {\n return {\n dependencies: givenDependencies<\n Statement,\n ResolvedStepType,\n Variables,\n GivenState\n >(statement, stepType, parsers as unknown as Parser<any>[]),\n step: addStep<\n ResolvedStepType,\n Statement,\n EmptyDependencies,\n Variables,\n GivenState,\n never,\n never,\n never,\n never,\n never\n >(statement, stepType, undefined, parsers as unknown as Parser<any>[]),\n };\n };\n\nconst givenStatement =\n <ResolvedStepType extends StepType, GivenState>(stepType: ResolvedStepType) =>\n <Statement extends ((...args: [...any]) => string) | string>(\n statement: Statement\n ) => {\n let normalizedStatement: Statement extends string\n ? () => string\n : Statement;\n if (isString(statement)) {\n normalizedStatement = (() => statement) as any;\n } else {\n normalizedStatement = statement as any;\n }\n type NormalizedStatement = typeof normalizedStatement;\n\n type Variables = Statement extends string ? [] : GetFunctionArgs<Statement>;\n const dependencyFunc = givenDependencies<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState\n >(normalizedStatement, stepType);\n const parsersFunc = givenParsers<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState\n >(normalizedStatement, stepType);\n const stepFunc = addStep<\n ResolvedStepType,\n NormalizedStatement,\n EmptyDependencies,\n Variables,\n GivenState,\n never,\n never,\n never,\n never,\n never\n >(normalizedStatement, stepType);\n return {\n dependencies: dependencyFunc,\n parsers: parsersFunc,\n step: stepFunc,\n };\n };\n\nexport const givenBuilder = <GivenState>() => {\n return {\n statement: givenStatement<\"given\", GivenState>(\"given\"),\n };\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n EmptyDependencies,\n EmptyObject,\n GetFunctionArgs,\n isString,\n RequiredOrOptional,\n StepType,\n} from \"./builderTypeUtils\";\nimport { addStep } from \"./common\";\nimport { Parser } from \"./parsers\";\n\nconst whenDependencies =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables,\n GivenState,\n WhenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n parsers?: Parser<any>[]\n ) =>\n <\n GivenDeps extends RequiredOrOptional<GivenState>,\n WhenDeps extends RequiredOrOptional<WhenState>,\n >(dependencies: {\n given?: GivenDeps;\n when?: WhenDeps;\n }) => {\n type RestrictedGivenState = {\n [K in keyof GivenState as K extends keyof GivenDeps\n ? K\n : never]: GivenDeps[K] extends \"optional\"\n ? GivenState[K] | undefined\n : GivenState[K];\n };\n type RestrictedWhenState = {\n [K in keyof WhenState as K extends keyof WhenDeps\n ? K\n : never]: WhenDeps[K] extends \"optional\"\n ? WhenState[K] | undefined\n : WhenState[K];\n };\n type Dependencies = {\n given: GivenDeps;\n when: WhenDeps;\n then: EmptyObject;\n };\n const fullDependencies: Dependencies = {\n given: dependencies.given ?? ({} as GivenDeps),\n when: dependencies.when ?? ({} as WhenDeps),\n then: {},\n };\n return {\n step: addStep<\n ResolvedStepType,\n Statement,\n Dependencies,\n Variables,\n GivenState,\n WhenState,\n never,\n RestrictedGivenState,\n RestrictedWhenState,\n never\n >(statement, stepType, fullDependencies, parsers),\n };\n };\n\nconst whenParsers =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables extends any[],\n GivenState,\n WhenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType\n ) =>\n <Parsers extends { [K in keyof Variables]: Parser<Variables[K]> }>(\n parsers: Parsers\n ) => {\n return {\n dependencies: whenDependencies<\n Statement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState\n >(statement, stepType, parsers as unknown as Parser<any>[]),\n step: addStep<\n ResolvedStepType,\n Statement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n never,\n never,\n never,\n never\n >(statement, stepType, undefined, parsers as unknown as Parser<any>[]),\n };\n };\n\nconst whenStatement =\n <ResolvedStepType extends StepType, GivenState, WhenState>(\n stepType: ResolvedStepType\n ) =>\n <Statement extends ((...args: [...any]) => string) | string>(\n statement: Statement\n ) => {\n let normalizedStatement: Statement extends string\n ? () => string\n : Statement;\n if (isString(statement)) {\n normalizedStatement = (() => statement) as any;\n } else {\n normalizedStatement = statement as any;\n }\n type NormalizedStatement = typeof normalizedStatement;\n\n type Variables = Statement extends string ? [] : GetFunctionArgs<Statement>;\n const dependencyFunc = whenDependencies<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState\n >(normalizedStatement, stepType);\n const parsersFunc = whenParsers<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState\n >(normalizedStatement, stepType);\n const stepFunc = addStep<\n ResolvedStepType,\n NormalizedStatement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n never,\n never,\n never,\n never\n >(normalizedStatement, stepType);\n return {\n dependencies: dependencyFunc,\n parsers: parsersFunc,\n step: stepFunc,\n };\n };\n\nexport const whenBuilder = <GivenState, WhenState>() => {\n return {\n statement: whenStatement<\"when\", GivenState, WhenState>(\"when\"),\n };\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n\nimport {\n EmptyDependencies,\n GetFunctionArgs,\n isString,\n RequiredOrOptional,\n StepType,\n} from \"./builderTypeUtils\";\nimport { addStep } from \"./common\";\nimport { Parser } from \"./parsers\";\n\nconst thenDependencies =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType,\n parsers?: Parser<any>[]\n ) =>\n <\n GivenDeps extends RequiredOrOptional<GivenState>,\n WhenDeps extends RequiredOrOptional<WhenState>,\n ThenDeps extends RequiredOrOptional<ThenState>,\n >(dependencies: {\n given?: GivenDeps;\n when?: WhenDeps;\n then?: ThenDeps;\n }) => {\n type RestrictedGivenState = {\n [K in keyof GivenState as K extends keyof GivenDeps\n ? K\n : never]: GivenDeps[K] extends \"optional\"\n ? GivenState[K] | undefined\n : GivenState[K];\n };\n type RestrictedWhenState = {\n [K in keyof WhenState as K extends keyof WhenDeps\n ? K\n : never]: WhenDeps[K] extends \"optional\"\n ? WhenState[K] | undefined\n : WhenState[K];\n };\n type RestrictedThenState = {\n [K in keyof ThenState as K extends keyof ThenDeps\n ? K\n : never]: ThenDeps[K] extends \"optional\"\n ? ThenState[K] | undefined\n : ThenState[K];\n };\n type Dependencies = {\n given: GivenDeps;\n when: WhenDeps;\n then: ThenDeps;\n };\n const fullDependencies: Dependencies = {\n given: dependencies.given ?? ({} as GivenDeps),\n when: dependencies.when ?? ({} as WhenDeps),\n then: dependencies.then ?? ({} as ThenDeps),\n };\n return {\n step: addStep<\n ResolvedStepType,\n Statement,\n Dependencies,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n RestrictedGivenState,\n RestrictedWhenState,\n RestrictedThenState\n >(statement, stepType, fullDependencies, parsers),\n };\n };\n\nconst thenParsers =\n <\n Statement extends (...args: any[]) => string,\n ResolvedStepType extends StepType,\n Variables extends any[],\n GivenState,\n WhenState,\n ThenState,\n >(\n statement: Statement,\n stepType: ResolvedStepType\n ) =>\n <Parsers extends { [K in keyof Variables]: Parser<Variables[K]> }>(\n parsers: Parsers\n ) => {\n return {\n dependencies: thenDependencies<\n Statement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState,\n ThenState\n >(statement, stepType, parsers as unknown as Parser<any>[]),\n step: addStep<\n ResolvedStepType,\n Statement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n never,\n never,\n never\n >(statement, stepType, undefined, parsers as unknown as Parser<any>[]),\n };\n };\n\nconst thenStatement =\n <ResolvedStepType extends StepType, GivenState, WhenState, ThenState>(\n stepType: ResolvedStepType\n ) =>\n <Statement extends ((...args: [...any]) => string) | string>(\n statement: Statement\n ) => {\n let normalizedStatement: Statement extends string\n ? () => string\n : Statement;\n if (isString(statement)) {\n normalizedStatement = (() => statement) as any;\n } else {\n normalizedStatement = statement as any;\n }\n type NormalizedStatement = typeof normalizedStatement;\n\n type Variables = Statement extends string ? [] : GetFunctionArgs<Statement>;\n const dependencyFunc = thenDependencies<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState,\n ThenState\n >(normalizedStatement, stepType);\n const parsersFunc = thenParsers<\n NormalizedStatement,\n ResolvedStepType,\n Variables,\n GivenState,\n WhenState,\n ThenState\n >(normalizedStatement, stepType);\n const stepFunc = addStep<\n ResolvedStepType,\n NormalizedStatement,\n EmptyDependencies,\n Variables,\n GivenState,\n WhenState,\n ThenState,\n never,\n never,\n never\n >(normalizedStatement, stepType);\n return {\n dependencies: dependencyFunc,\n parsers: parsersFunc,\n step: stepFunc,\n };\n };\n\nexport const thenBuilder = <GivenState, WhenState, ThenState>() => {\n return {\n statement: thenStatement<\"then\", GivenState, WhenState, ThenState>(\"then\"),\n };\n};\n","import _ from \"lodash\";\n\nexport type WorldState<State> = {\n readonly [K in keyof State]?: State[K];\n};\n\nexport type MergeableWorldState<T> = WorldState<T> & {\n merge: (newState: Partial<T>) => void;\n};\n\nfunction mergeCustomizer(objValue: unknown, srcValue: unknown) {\n if (_.isArray(objValue)) {\n return objValue.concat(srcValue);\n } else if (objValue && !_.isPlainObject(objValue) && objValue !== srcValue) {\n throw new Error(\n `Merge would have destroyed previous value ${objValue} with ${srcValue}`\n );\n }\n return objValue;\n}\n\nexport const createMergeableState = <T>(\n state: WorldState<T>\n): MergeableWorldState<T> => {\n return {\n ...state,\n merge: (newState: Partial<T>) => {\n state = _.merge({ ...state }, newState, mergeCustomizer);\n },\n };\n};\n\nexport type MergeableWorld<Given, When, Then> = {\n given: MergeableWorldState<Given>;\n when: MergeableWorldState<When>;\n then: MergeableWorldState<Then>;\n};\n\nexport class BasicWorld<Given, When, Then> {\n private givenState: WorldState<Given> = {};\n private whenState: WorldState<When> = {};\n private thenState: WorldState<Then> = {};\n\n public get given(): MergeableWorldState<Given> {\n return {\n ...this.givenState,\n merge: (newState: Partial<Given>) => {\n this.givenState = _.merge(\n { ...this.givenState },\n newState,\n mergeCustomizer\n );\n },\n };\n }\n\n public get when(): MergeableWorldState<When> {\n return {\n ...this.whenState,\n merge: (newState: Partial<When>) => {\n this.whenState = _.merge(\n { ...this.whenState },\n newState,\n mergeCustomizer\n );\n },\n };\n }\n\n public get then(): MergeableWorldState<Then> {\n return {\n ...this.thenState,\n merge: (newState: Partial<Then>) => {\n this.thenState = _.merge(\n { ...this.thenState },\n newState,\n mergeCustomizer\n );\n },\n };\n }\n}\n\nexport const createBasicWorld = <Given, When, Then>(): MergeableWorld<\n Given,\n When,\n Then\n> => {\n return new BasicWorld<Given, When, Then>();\n};\n","import ts from \"typescript\";\nimport { StepDefinitionMeta } from \"./types.js\";\n\ntype StepType = \"given\" | \"when\" | \"then\";\n\nconst BUILDER_NAMES: Record<string, StepType> = {\n givenBuilder: \"given\",\n whenBuilder: \"when\",\n thenBuilder: \"then\",\n};\n\nexport function extractStepDefinitions(\n filePaths: string[],\n tsConfigPath?: string\n): StepDefinitionMeta[] {\n const configPath =\n tsConfigPath ?? ts.findConfigFile(process.cwd(), ts.sys.fileExists);\n let compilerOptions: ts.CompilerOptions = {\n target: ts.ScriptTarget.ESNext,\n module: ts.ModuleKind.ESNext,\n moduleResolution: ts.ModuleResolutionKind.Node10,\n strict: true,\n esModuleInterop: true,\n };\n\n if (configPath) {\n const configFile = ts.readConfigFile(configPath, ts.sys.readFile);\n if (!configFile.error) {\n const parsed = ts.parseJsonConfigFileContent(\n configFile.config,\n ts.sys,\n configPath.replace(/[/\\\\][^/\\\\]+$/, \"\")\n );\n compilerOptions = parsed.options;\n }\n }\n\n // Ensure noEmit so we don't write files\n compilerOptions.noEmit = true;\n\n const program = ts.createProgram(filePaths, compilerOptions);\n const checker = program.getTypeChecker();\n const results: StepDefinitionMeta[] = [];\n\n for (const filePath of filePaths) {\n const sourceFile = program.getSourceFile(filePath);\n if (!sourceFile) continue;\n const fileResults = extractFromSourceFile(sourceFile, checker);\n results.push(...fileResults);\n }\n\n return results;\n}\n\nfunction extractFromSourceFile(\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker\n): StepDefinitionMeta[] {\n const results: StepDefinitionMeta[] = [];\n\n function visit(node: ts.Node) {\n // Look for .register() call expressions\n if (\n ts.isCallExpression(node) &&\n ts.isPropertyAccessExpression(node.expression) &&\n node.expression.name.text === \"register\"\n ) {\n const meta = extractFromRegisterCall(node, sourceFile, checker);\n if (meta) {\n results.push(meta);\n }\n }\n ts.forEachChild(node, visit);\n }\n\n visit(sourceFile);\n return results;\n}\n\nfunction extractFromRegisterCall(\n registerCall: ts.CallExpression,\n sourceFile: ts.SourceFile,\n checker: ts.TypeChecker\n): StepDefinitionMeta | null {\n // Walk backwards through the method chain to find all parts\n // Pattern: builder().statement(...).dependencies?(...).step(...).register()\n // Or: Variable(\"...\").dependencies?(...).step(...).register()\n\n const chain = collectCallChain(registerCall);\n\n let stepType: StepType | null = null;\n let expression: string | null = null;\n let dependencies: StepDefinitionMeta[\"dependencies\"] = {\n given: {},\n when: {},\n then: {},\n };\n let produces: string[] = [];\n\n for (const link of chain) {\n const name = getCallName(link);\n if (!name) continue;\n\n if (name === \"register\") {\n // Already at register, continue\n continue;\n }\n\n if (name === \"step\") {\n produces = extractProducedKeys(link, checker);\n continue;\n }\n\n if (name === \"dependencies\") {\n dependencies = extractDependencies(link);\n continue;\n }\n\n if (name === \"statement\") {\n expression = extractExpression(link);\n // Try to find the builder type by continuing up the chain\n continue;\n }\n\n // Check if this is a builder call like givenBuilder()\n if (BUILDER_NAMES[name]) {\n stepType = BUILDER_NAMES[name];\n continue;\n }\n }\n\n // If we didn't find the builder or expression in the chain, try the \"re-exported\" pattern:\n // const Given = givenBuilder<T>().statement;\n // Given(\"foo\").step(...).register()\n if (!stepType || !expression) {\n const reExport = resolveReExportedCall(chain, checker);\n if (reExport) {\n if (!stepType) stepType = reExport.stepType;\n if (!expression) expression = reExport.expression;\n }\n }\n\n if (!stepType || !expression) {\n return null;\n }\n\n const line =\n sourceFile.getLineAndCharacterOfPosition(registerCall.getStart()).line + 1;\n\n return {\n stepType,\n expression,\n dependencies,\n produces,\n sourceFile: sourceFile.fileName,\n line,\n };\n}\n\n/**\n * Collect all call expressions in the method chain, from register() back to the origin.\n */\nfunction collectCallChain(call: ts.CallExpression): ts.CallExpression[] {\n const chain: ts.CallExpression[] = [call];\n let current: ts.Expression = call.expression;\n\n while (true) {\n // Walk through PropertyAccessExpression to find the next call\n if (ts.isPropertyAccessExpression(current)) {\n current = current.expression;\n }\n\n if (ts.isCallExpression(current)) {\n chain.push(current);\n current = current.expression;\n } else {\n break;\n }\n }\n\n return chain;\n}\n\nfunction getCallName(call: ts.CallExpression): string | null {\n const expr = call.expression;\n\n // .method() pattern\n if (ts.isPropertyAccessExpression(expr)) {\n return expr.name.text;\n }\n\n // direct call: functionName()\n if (ts.isIdentifier(expr)) {\n return expr.text;\n }\n\n return null;\n}\n\nfunction extractExpression(statementCall: ts.CallExpression): string | null {\n const arg = statementCall.arguments[0];\n if (!arg) return null;\n\n // String literal: .statement(\"a user\")\n if (ts.isStringLiteral(arg)) {\n return arg.text;\n }\n\n // Arrow function with template literal: .statement((name: string) => `a user named ${name}`)\n if (ts.isArrowFunction(arg)) {\n return extractExpressionFromArrowFunction(arg);\n }\n\n return null;\n}\n\nfunction extractExpressionFromArrowFunction(\n fn: ts.ArrowFunction\n): string | null {\n const params = fn.parameters.map((p) => p.name.getText());\n\n // The body should be a template expression or string literal\n let body = fn.body;\n\n // If wrapped in a block with a return, unwrap\n if (ts.isBlock(body)) {\n const returnStmt = body.statements.find(ts.isReturnStatement);\n if (returnStmt?.expression) {\n body = returnStmt.expression;\n } else {\n return null;\n }\n }\n\n if (ts.isTemplateExpression(body)) {\n return reconstructExpressionFromTemplate(body, params);\n }\n\n if (ts.isNoSubstitutionTemplateLiteral(body)) {\n return body.text;\n }\n\n return null;\n}\n\nfunction reconstructExpressionFromTemplate(\n template: ts.TemplateExpression,\n paramNames: string[]\n): string {\n let result = template.head.text;\n\n for (const span of template.templateSpans) {\n if (ts.isIdentifier(span.expression) && paramNames.includes(span.expression.text)) {\n result += \"{string}\";\n } else {\n // Non-parameter expression, use {string} as fallback\n result += \"{string}\";\n }\n result += span.literal.text;\n }\n\n return result;\n}\n\nfunction extractDependencies(\n depsCall: ts.CallExpression\n): StepDefinitionMeta[\"dependencies\"] {\n const deps: StepDefinitionMeta[\"dependencies\"] = {\n given: {},\n when: {},\n then: {},\n };\n\n const arg = depsCall.arguments[0];\n if (!arg || !ts.isObjectLiteralExpression(arg)) return deps;\n\n for (const prop of arg.properties) {\n if (!ts.isPropertyAssignment(prop) || !ts.isIdentifier(prop.name))\n continue;\n\n const phase = prop.name.text as \"given\" | \"when\" | \"then\";\n if (!deps[phase]) continue;\n\n if (ts.isObjectLiteralExpression(prop.initializer)) {\n for (const innerProp of prop.initializer.properties) {\n if (\n ts.isPropertyAssignment(innerProp) &&\n ts.isIdentifier(innerProp.name) &&\n ts.isStringLiteral(innerProp.initializer)\n ) {\n const val = innerProp.initializer.text;\n if (val === \"required\" || val === \"optional\") {\n deps[phase][innerProp.name.text] = val;\n }\n }\n }\n }\n }\n\n return deps;\n}\n\nfunction extractProducedKeys(\n stepCall: ts.CallExpression,\n checker: ts.TypeChecker\n): string[] {\n const callback = stepCall.arguments[0];\n if (!callback) return [];\n\n // Try to get the return type of the callback by analyzing its body\n if (ts.isArrowFunction(callback) || ts.isFunctionExpression(callback)) {\n return extractProducedKeysFromCallback(callback, checker);\n }\n\n return [];\n}\n\nfunction extractProducedKeysFromCallback(\n callback: ts.ArrowFunction | ts.FunctionExpression,\n checker: ts.TypeChecker\n): string[] {\n const body = callback.body;\n\n // Concise arrow: () => ({ key: value })\n if (!ts.isBlock(body)) {\n return extractKeysFromExpression(body, checker);\n }\n\n // Block body: look at return statements\n const keys = new Set<string>();\n function visitReturn(node: ts.Node) {\n if (ts.isReturnStatement(node) && node.expression) {\n for (const key of extractKeysFromExpression(node.expression, checker)) {\n keys.add(key);\n }\n }\n ts.forEachChild(node, visitReturn);\n }\n visitReturn(body);\n return [...keys];\n}\n\nfunction extractKeysFromExpression(\n expr: ts.Expression,\n checker: ts.TypeChecker\n): string[] {\n // Unwrap parenthesized expressions\n while (ts.isParenthesizedExpression(expr)) {\n expr = expr.expression;\n }\n\n // Object literal: { user: ..., token: ... }\n if (ts.isObjectLiteralExpression(expr)) {\n return expr.properties\n .filter(\n (p): p is ts.PropertyAssignment | ts.ShorthandPropertyAssignment =>\n ts.isPropertyAssignment(p) || ts.isShorthandPropertyAssignment(p)\n )\n .map((p) => p.name.getText())\n .filter(Boolean);\n }\n\n // Try type checker as fallback\n try {\n const type = checker.getTypeAtLocation(expr);\n return type\n .getProperties()\n .map((p) => p.name)\n .filter((n) => n !== \"merge\");\n } catch {\n return [];\n }\n}\n\ninterface ReExportResult {\n stepType: StepType;\n expression: string | null;\n}\n\nfunction resolveReExportedCall(\n chain: ts.CallExpression[],\n checker: ts.TypeChecker\n): ReExportResult | null {\n // Look for the pattern: Variable(\"...\")... where Variable was assigned from builderType().statement\n // The last call in the chain (furthest from register) should be the variable call\n\n const lastCall = chain[chain.length - 1];\n if (!lastCall) return null;\n\n const expr = lastCall.expression;\n\n // If it's an identifier (like \"Given\", \"When\", \"Then\"), trace its declaration\n let identifier: ts.Identifier | null = null;\n if (ts.isIdentifier(expr)) {\n identifier = expr;\n } else if (\n ts.isPropertyAccessExpression(expr) &&\n ts.isIdentifier(expr.expression)\n ) {\n identifier = expr.expression;\n }\n\n if (!identifier) return null;\n\n const symbol = checker.getSymbolAtLocation(identifier);\n if (!symbol) return null;\n\n const decl = symbol.valueDeclaration;\n if (!decl || !ts.isVariableDeclaration(decl) || !decl.initializer)\n return null;\n\n // Check if initializer is builderType<T>().statement\n const init = decl.initializer;\n\n // Pattern: givenBuilder<T>().statement (PropertyAccessExpression)\n if (ts.isPropertyAccessExpression(init) && init.name.text === \"statement\") {\n const callExpr = init.expression;\n if (ts.isCallExpression(callExpr)) {\n const callee = callExpr.expression;\n if (ts.isIdentifier(callee) && BUILDER_NAMES[callee.text]) {\n // The lastCall IS the statement call — extract expression from it\n const expression = extractExpression(lastCall);\n return {\n stepType: BUILDER_NAMES[callee.text],\n expression,\n };\n }\n }\n }\n\n return null;\n}\n","import * as fs from \"node:fs\";\nimport { GherkinClassicTokenMatcher, Parser, AstBuilder } from \"@cucumber/gherkin\";\nimport * as messages from \"@cucumber/messages\";\nimport { ParsedScenario, ParsedStep } from \"./types.js\";\n\ntype GherkinKeyword = \"Given\" | \"When\" | \"Then\" | \"And\" | \"But\";\n\nexport function parseFeatureFiles(filePaths: string[]): ParsedScenario[] {\n const scenarios: ParsedScenario[] = [];\n\n for (const filePath of filePaths) {\n const content = fs.readFileSync(filePath, \"utf-8\");\n const parsed = parseFeatureContent(content, filePath);\n scenarios.push(...parsed);\n }\n\n return scenarios;\n}\n\nexport function parseFeatureContent(\n content: string,\n filePath: string\n): ParsedScenario[] {\n const newId = messages.IdGenerator.uuid();\n const builder = new AstBuilder(newId);\n const matcher = new GherkinClassicTokenMatcher();\n const parser = new Parser(builder, matcher);\n\n const gherkinDocument: messages.GherkinDocument = parser.parse(content);\n const feature = gherkinDocument.feature;\n if (!feature) return [];\n\n // Collect background steps at the feature level\n const featureBackground: messages.Step[] = [];\n const scenarios: ParsedScenario[] = [];\n\n for (const child of feature.children) {\n if (child.background) {\n featureBackground.push(...child.background.steps);\n }\n\n if (child.scenario) {\n scenarios.push(\n ...expandScenario(child.scenario, featureBackground, filePath)\n );\n }\n\n if (child.rule) {\n // Rules can have their own backgrounds\n const ruleBackground: messages.Step[] = [...featureBackground];\n for (const ruleChild of child.rule.children) {\n if (ruleChild.background) {\n ruleBackground.push(...ruleChild.background.steps);\n }\n if (ruleChild.scenario) {\n scenarios.push(\n ...expandScenario(ruleChild.scenario, ruleBackground, filePath)\n );\n }\n }\n }\n }\n\n return scenarios;\n}\n\nfunction expandScenario(\n scenario: messages.Scenario,\n backgroundSteps: messages.Step[],\n filePath: string\n): ParsedScenario[] {\n const hasExamples =\n scenario.examples.length > 0 &&\n scenario.examples.some((e) => e.tableBody.length > 0);\n\n if (!hasExamples) {\n // Regular scenario\n const bgParsed = convertSteps(backgroundSteps);\n const scenarioParsed = convertSteps(scenario.steps);\n const allSteps = resolveEffectiveKeywords([...bgParsed, ...scenarioParsed]);\n\n return [\n {\n name: scenario.name,\n file: filePath,\n steps: allSteps,\n },\n ];\n }\n\n // Scenario Outline — expand with each example row\n const results: ParsedScenario[] = [];\n for (const example of scenario.examples) {\n if (!example.tableHeader || example.tableBody.length === 0) continue;\n const headers = example.tableHeader.cells.map((c) => c.value);\n\n for (const row of example.tableBody) {\n const values = row.cells.map((c) => c.value);\n const substitution: Record<string, string> = {};\n headers.forEach((h, i) => {\n substitution[h] = values[i];\n });\n\n const bgParsed = convertSteps(backgroundSteps);\n const scenarioSteps = convertSteps(scenario.steps).map((step) => ({\n ...step,\n text: substituteExampleValues(step.text, substitution),\n }));\n const allSteps = resolveEffectiveKeywords([...bgParsed, ...scenarioSteps]);\n\n results.push({\n name: `${scenario.name} (${values.join(\", \")})`,\n file: filePath,\n steps: allSteps,\n });\n }\n }\n\n return results;\n}\n\nfunction convertSteps(\n steps: readonly messages.Step[]\n): Omit<ParsedStep, \"effectiveKeyword\">[] {\n return steps.map((step) => ({\n keyword: normalizeKeyword(step.keyword),\n text: step.text,\n line: step.location.line,\n // step.location.column points to the keyword start; shift past the\n // keyword (which includes a trailing space) so column points to the\n // start of the step text. This makes `column + text.length` produce\n // the correct end position for diagnostic ranges.\n column: (step.location.column ?? 1) + step.keyword.length,\n }));\n}\n\nfunction normalizeKeyword(keyword: string): GherkinKeyword {\n const trimmed = keyword.trim();\n // Gherkin keywords may include trailing space, e.g. \"Given \"\n if (trimmed === \"Given\") return \"Given\";\n if (trimmed === \"When\") return \"When\";\n if (trimmed === \"Then\") return \"Then\";\n if (trimmed === \"And\") return \"And\";\n if (trimmed === \"But\") return \"But\";\n // Fallback: treat as Given (shouldn't happen with valid Gherkin)\n return \"Given\";\n}\n\nfunction resolveEffectiveKeywords(\n steps: Omit<ParsedStep, \"effectiveKeyword\">[]\n): ParsedStep[] {\n let lastEffective: \"Given\" | \"When\" | \"Then\" = \"Given\";\n\n return steps.map((step) => {\n let effectiveKeyword: \"Given\" | \"When\" | \"Then\";\n if (step.keyword === \"And\" || step.keyword === \"But\") {\n effectiveKeyword = lastEffective;\n } else {\n effectiveKeyword = step.keyword as \"Given\" | \"When\" | \"Then\";\n }\n lastEffective = effectiveKeyword;\n\n return {\n ...step,\n effectiveKeyword,\n };\n });\n}\n\nfunction substituteExampleValues(\n text: string,\n substitution: Record<string, string>\n): string {\n let result = text;\n for (const [key, value] of Object.entries(substitution)) {\n result = result.replace(new RegExp(`<${key}>`, \"g\"), value);\n }\n return result;\n}\n","import { MatchedStep, ParsedScenario, StepDefinitionMeta } from \"./types.js\";\n\ninterface CompiledPattern {\n regex: RegExp;\n definition: StepDefinitionMeta;\n}\n\nfunction compileDefinitions(\n definitions: StepDefinitionMeta[]\n): CompiledPattern[] {\n const compiled: CompiledPattern[] = [];\n for (const def of definitions) {\n try {\n // Replace {paramType} placeholders with (.+) to match any value,\n // regardless of which parser placeholder ({string}, {int}, ...) the\n // step definition declared.\n const placeholder = \"###PLACEHOLDER###\";\n const regexStr = def.expression\n .replace(/\\{[^}]+\\}/g, placeholder)\n .replace(/[.*+?^$()|[\\]\\\\]/g, \"\\\\$&\")\n .replace(new RegExp(placeholder, \"g\"), \"(.+)\");\n compiled.push({\n regex: new RegExp(`^${regexStr}$`, \"i\"),\n definition: def,\n });\n } catch {\n // Skip definitions with invalid expressions\n }\n }\n return compiled;\n}\n\nexport function matchScenarioSteps(\n scenario: ParsedScenario,\n definitions: StepDefinitionMeta[]\n): MatchedStep[] {\n const compiled = compileDefinitions(definitions);\n\n return scenario.steps.map(step => {\n const matches = findMatches(step.text, step.effectiveKeyword, compiled);\n return {\n ...step,\n definitions: matches,\n };\n });\n}\n\nexport function findMatchingDefinitions(\n text: string,\n effectiveKeyword: \"Given\" | \"When\" | \"Then\",\n definitions: StepDefinitionMeta[]\n): StepDefinitionMeta[] {\n const compiled = compileDefinitions(definitions);\n return findMatches(text, effectiveKeyword, compiled);\n}\n\nfunction findMatches(\n text: string,\n effectiveKeyword: \"Given\" | \"When\" | \"Then\",\n compiled: CompiledPattern[]\n): StepDefinitionMeta[] {\n const keywordToStepType: Record<string, string> = {\n Given: \"given\",\n When: \"when\",\n Then: \"then\",\n };\n const expectedStepType = keywordToStepType[effectiveKeyword];\n\n // First try to match with the correct step type\n const typedMatches: StepDefinitionMeta[] = [];\n for (const { regex, definition } of compiled) {\n if (definition.stepType !== expectedStepType) continue;\n if (regex.test(text)) typedMatches.push(definition);\n }\n\n if (typedMatches.length > 0) return typedMatches;\n\n // Fallback: match any step type\n const fallbackMatches: StepDefinitionMeta[] = [];\n for (const { regex, definition } of compiled) {\n if (regex.test(text)) fallbackMatches.push(definition);\n }\n\n return fallbackMatches;\n}\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\n\nexport const ambiguousStepRule: AnalysisRule = {\n name: \"ambiguous-step\",\n\n check(\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n ): Diagnostic[] {\n return matchedSteps\n .filter((step) => step.definitions.length > 1)\n .map((step) => {\n const locations = step.definitions\n .map((d) => `${d.sourceFile}:${d.line}`)\n .join(\", \");\n return {\n file: scenario.file,\n range: {\n startLine: step.line,\n startColumn: step.column,\n endLine: step.line,\n endColumn: step.column + step.text.length,\n },\n severity: \"error\" as const,\n message: `Step \"${step.text}\" matches multiple step definitions: ${locations}`,\n rule: \"ambiguous-step\",\n source: \"step-forge\" as const,\n };\n });\n },\n};\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\n\nexport const dependencyRule: AnalysisRule = {\n name: \"dependency-check\",\n\n check(\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n ): Diagnostic[] {\n const diagnostics: Diagnostic[] = [];\n const produced = {\n given: new Set<string>(),\n when: new Set<string>(),\n then: new Set<string>(),\n };\n\n for (const step of matchedSteps) {\n if (step.definitions.length !== 1) continue;\n\n const { dependencies, produces, stepType } = step.definitions[0];\n\n // Collect all missing required dependencies for this step\n const missing: Record<string, string[]> = {};\n for (const phase of [\"given\", \"when\", \"then\"] as const) {\n for (const [key, requirement] of Object.entries(dependencies[phase])) {\n if (requirement === \"required\" && !produced[phase].has(key)) {\n if (!missing[phase]) {\n missing[phase] = [];\n }\n missing[phase].push(key);\n }\n }\n }\n\n if (Object.keys(missing).length > 0) {\n const lines = Object.entries(missing).map(\n ([phase, keys]) =>\n `${phase.charAt(0).toUpperCase() + phase.slice(1)}: ${keys.map((k) => `${phase}.${k}`).join(\", \")}`\n );\n const message =\n \"Missing required dependencies:\\n\" + lines.join(\"\\n\");\n\n diagnostics.push({\n file: scenario.file,\n range: {\n startLine: step.line,\n startColumn: step.column,\n endLine: step.line,\n endColumn: step.column + step.text.length,\n },\n severity: \"error\",\n message,\n rule: \"dependency-check\",\n source: \"step-forge\",\n });\n }\n\n // Add produced keys for this step\n for (const key of produces) {\n produced[stepType].add(key);\n }\n }\n\n return diagnostics;\n },\n};\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\n\nexport const undefinedStepRule: AnalysisRule = {\n name: \"undefined-step\",\n\n check(\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n ): Diagnostic[] {\n return matchedSteps\n .filter((step) => step.definitions.length === 0)\n .map((step) => ({\n file: scenario.file,\n range: {\n startLine: step.line,\n startColumn: step.column,\n endLine: step.line,\n endColumn: step.column + step.text.length,\n },\n severity: \"error\" as const,\n message: `Step \"${step.text}\" does not match any step definition`,\n rule: \"undefined-step\",\n source: \"step-forge\" as const,\n }));\n },\n};\n","import {\n AnalysisRule,\n Diagnostic,\n MatchedStep,\n ParsedScenario,\n} from \"../types.js\";\nimport { ambiguousStepRule } from \"./ambiguousStepRule.js\";\nimport { dependencyRule } from \"./dependencyRule.js\";\nimport { undefinedStepRule } from \"./undefinedStepRule.js\";\n\nexport const defaultRules: AnalysisRule[] = [\n undefinedStepRule,\n ambiguousStepRule,\n dependencyRule,\n];\n\nexport function runRules(\n rules: AnalysisRule[],\n scenario: ParsedScenario,\n matchedSteps: MatchedStep[]\n): Diagnostic[] {\n return rules.flatMap((rule) => rule.check(scenario, matchedSteps));\n}\n","import { glob } from \"node:fs/promises\";\nimport * as path from \"node:path\";\nimport { extractStepDefinitions } from \"./stepExtractor.js\";\nimport { parseFeatureFiles, parseFeatureContent } from \"./gherkinParser.js\";\nimport {\n matchScenarioSteps,\n findMatchingDefinitions,\n} from \"./stepMatcher.js\";\nimport { defaultRules, runRules } from \"./rules/index.js\";\nimport type {\n AnalyzerConfig,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n MatchedStep,\n ParsedStep,\n} from \"./types.js\";\n\nexport type {\n AnalyzerConfig,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n MatchedStep,\n ParsedStep,\n};\n\nexport {\n extractStepDefinitions,\n parseFeatureFiles,\n parseFeatureContent,\n matchScenarioSteps,\n findMatchingDefinitions,\n defaultRules,\n};\n\nexport interface AnalyzeOptions {\n rules?: AnalysisRule[];\n}\n\nexport async function analyze(\n config: AnalyzerConfig,\n options?: AnalyzeOptions\n): Promise<Diagnostic[]> {\n const rules = options?.rules ?? defaultRules;\n\n // 1. Resolve file globs to paths\n const stepFilePaths = await resolveGlobs(config.stepFiles);\n const featureFilePaths = await resolveGlobs(config.featureFiles);\n\n if (stepFilePaths.length === 0) {\n return [];\n }\n if (featureFilePaths.length === 0) {\n return [];\n }\n\n // 2. Extract step metadata from step files\n const stepDefinitions = extractStepDefinitions(\n stepFilePaths,\n config.tsConfigPath\n );\n\n // 3. Parse feature files\n const scenarios = parseFeatureFiles(featureFilePaths);\n\n // 4. For each scenario, match steps and run rules\n const diagnostics: Diagnostic[] = [];\n for (const scenario of scenarios) {\n const matchedSteps = matchScenarioSteps(scenario, stepDefinitions);\n const scenarioDiags = runRules(rules, scenario, matchedSteps);\n diagnostics.push(...scenarioDiags);\n }\n\n return diagnostics;\n}\n\nasync function resolveGlobs(patterns: string[]): Promise<string[]> {\n const files: string[] = [];\n for (const pattern of patterns) {\n for await (const file of glob(pattern)) {\n files.push(path.resolve(file));\n }\n }\n // Deduplicate\n return [...new Set(files)];\n}\n","import { givenBuilder } from \"./given\";\nimport { thenBuilder } from \"./then\";\nimport { whenBuilder } from \"./when\";\n\nexport const createBuilders = <GivenState, WhenState, ThenState>() => {\n return {\n Given: givenBuilder<GivenState>().statement,\n When: whenBuilder<GivenState, WhenState>().statement,\n Then: thenBuilder<GivenState, WhenState, ThenState>().statement,\n };\n};\n","import { givenBuilder } from \"./given\";\nimport { whenBuilder } from \"./when\";\nimport { thenBuilder } from \"./then\";\nimport { BasicWorld } from \"./world\";\nimport {\n stringParser,\n intParser,\n numberParser,\n booleanParser,\n} from \"./parsers\";\nimport type { Parser } from \"./parsers\";\nimport {\n analyze,\n extractStepDefinitions,\n parseFeatureFiles,\n parseFeatureContent,\n matchScenarioSteps,\n findMatchingDefinitions,\n defaultRules,\n} from \"./analyzer/index\";\nimport type {\n AnalyzerConfig,\n AnalyzeOptions,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n ParsedStep,\n MatchedStep,\n} from \"./analyzer/index\";\nimport { createBuilders } from \"./init\";\n\nexport {\n givenBuilder,\n whenBuilder,\n thenBuilder,\n BasicWorld,\n stringParser,\n intParser,\n numberParser,\n booleanParser,\n createBuilders,\n};\n\nexport type { Parser };\nexport type { StateFromDependencies } from \"./typeHelpers\";\n\nexport const analyzer = {\n analyze,\n extractStepDefinitions,\n parseFeatureFiles,\n parseFeatureContent,\n matchScenarioSteps,\n findMatchingDefinitions,\n defaultRules,\n};\n\nexport type {\n AnalyzerConfig,\n AnalyzeOptions,\n AnalysisRule,\n Diagnostic,\n StepDefinitionMeta,\n ParsedScenario,\n ParsedStep,\n MatchedStep,\n};\n"],"mappings":"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"}