or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dotnet.mdexpression-factory.mdgo.mdindex.mdjava.mdjavascript-typescript.mdparameter-types.mdpython.mdruby.md

javascript-typescript.mddocs/

0

# JavaScript/TypeScript Implementation

1

2

Complete TypeScript implementation with full type safety, dual package support (ESM/CJS), and comprehensive API coverage for browser and Node.js environments.

3

4

## Package Information

5

6

- **Package Name**: `@cucumber/cucumber-expressions`

7

- **Language**: TypeScript/JavaScript

8

- **Installation**: `npm install @cucumber/cucumber-expressions`

9

- **Entry Points**: ESM (`dist/esm/src/index.js`), CJS (`dist/cjs/src/index.js`)

10

- **Type Definitions**: `dist/cjs/src/index.d.ts`

11

12

## Core Imports

13

14

```typescript

15

import {

16

CucumberExpression,

17

ParameterType,

18

ParameterTypeRegistry,

19

ExpressionFactory,

20

CucumberExpressionGenerator,

21

Argument,

22

GeneratedExpression,

23

RegularExpression

24

} from '@cucumber/cucumber-expressions';

25

```

26

27

For CommonJS environments:

28

29

```javascript

30

const {

31

CucumberExpression,

32

ParameterTypeRegistry,

33

ExpressionFactory

34

} = require('@cucumber/cucumber-expressions');

35

```

36

37

## Capabilities

38

39

### Expression Creation and Matching

40

41

Create and match Cucumber expressions with full type safety and parameter extraction.

42

43

```typescript { .api }

44

/**

45

* Main class for parsing and matching Cucumber expressions

46

*/

47

class CucumberExpression implements Expression {

48

/**

49

* Create a new Cucumber expression

50

* @param expression - The Cucumber expression string

51

* @param parameterTypeRegistry - Registry containing parameter types

52

*/

53

constructor(expression: string, parameterTypeRegistry: ParameterTypeRegistry);

54

55

/**

56

* Match text against this expression and extract arguments

57

* @param text - Text to match against the expression

58

* @returns Array of matched arguments or null if no match

59

*/

60

match(text: string): readonly Argument[] | null;

61

62

/** The original expression string */

63

readonly source: string;

64

65

/** The compiled regular expression */

66

readonly regexp: RegExp;

67

68

/** The abstract syntax tree representation */

69

readonly ast: Node;

70

}

71

72

/**

73

* Common interface for all expression types

74

*/

75

interface Expression {

76

/** The original expression string */

77

readonly source: string;

78

79

/**

80

* Match text against this expression

81

* @param text - Text to match

82

* @returns Array of matched arguments or null if no match

83

*/

84

match(text: string): readonly Argument[] | null;

85

}

86

```

87

88

**Usage Examples:**

89

90

```typescript

91

import { CucumberExpression, ParameterTypeRegistry } from '@cucumber/cucumber-expressions';

92

93

// Create registry with built-in parameter types

94

const registry = new ParameterTypeRegistry();

95

96

// Simple integer parameter

97

const expr1 = new CucumberExpression('I have {int} cucumbers', registry);

98

const args1 = expr1.match('I have 42 cucumbers');

99

console.log(args1?.[0].getValue()); // 42 (number)

100

101

// Multiple parameters

102

const expr2 = new CucumberExpression('I have {int} {word} and {float} {word}', registry);

103

const args2 = expr2.match('I have 42 cucumbers and 3.5 apples');

104

console.log(args2?.[0].getValue()); // 42 (number)

105

console.log(args2?.[1].getValue()); // "cucumbers" (string)

106

console.log(args2?.[2].getValue()); // 3.5 (number)

107

console.log(args2?.[3].getValue()); // "apples" (string)

108

109

// Optional text

110

const expr3 = new CucumberExpression('I have {int} cucumber(s)', registry);

111

console.log(expr3.match('I have 1 cucumber')); // matches

112

console.log(expr3.match('I have 5 cucumbers')); // matches

113

114

// Alternative text

115

const expr4 = new CucumberExpression('I put it in my belly/stomach', registry);

116

console.log(expr4.match('I put it in my belly')); // matches

117

console.log(expr4.match('I put it in my stomach')); // matches

118

```

119

120

### Parameter Type Definition

121

122

Define custom parameter types with regex patterns and transformation functions.

123

124

```typescript { .api }

125

/**

126

* Defines a parameter type with name, patterns, and transformer

127

*/

128

class ParameterType<T> {

129

/**

130

* Create a new parameter type

131

* @param name - Name used in expressions (e.g., 'color' for {color})

132

* @param regexps - Regular expression patterns to match

133

* @param type - Constructor or factory for the result type

134

* @param transform - Function to transform matched strings to result type

135

* @param useForSnippets - Whether to use this type for snippet generation

136

* @param preferForRegexpMatch - Whether to prefer this type in regexp matches

137

* @param builtin - Whether this is a built-in parameter type

138

*/

139

constructor(

140

name: string | undefined,

141

regexps: RegExps,

142

type: Constructor<T> | Factory<T> | null,

143

transform?: (...match: string[]) => T | PromiseLike<T>,

144

useForSnippets?: boolean,

145

preferForRegexpMatch?: boolean,

146

builtin?: boolean

147

);

148

149

/**

150

* Compare two parameter types for sorting

151

*/

152

static compare(pt1: ParameterType<unknown>, pt2: ParameterType<unknown>): number;

153

154

/**

155

* Check if a parameter type name is valid

156

*/

157

static checkParameterTypeName(typeName: string): void;

158

159

/**

160

* Test if a parameter type name is valid

161

*/

162

static isValidParameterTypeName(typeName: string): boolean;

163

164

/** The parameter type name */

165

readonly name: string | undefined;

166

167

/** The type constructor or factory */

168

readonly type: Constructor<T> | Factory<T> | null;

169

170

/** Whether to use for snippet generation */

171

readonly useForSnippets: boolean;

172

173

/** Whether to prefer for regexp matching */

174

readonly preferForRegexpMatch: boolean;

175

176

/** Whether this is a built-in type */

177

readonly builtin: boolean;

178

179

/** The regular expression strings */

180

readonly regexpStrings: readonly string[];

181

182

/**

183

* Transform matched groups to the target type

184

* @param thisObj - Context object for transformation

185

* @param groupValues - Matched string groups

186

* @returns Transformed value

187

*/

188

transform(thisObj: unknown, groupValues: string[] | null): T;

189

}

190

191

/**

192

* Type definitions for parameter type construction

193

*/

194

type RegExps = readonly (string | RegExp)[] | string | RegExp;

195

type Constructor<T> = new (...args: any[]) => T;

196

type Factory<T> = (...args: any[]) => T;

197

```

198

199

**Usage Examples:**

200

201

```typescript

202

import { ParameterType, ParameterTypeRegistry } from '@cucumber/cucumber-expressions';

203

204

// Custom color parameter type

205

const colorType = new ParameterType(

206

'color',

207

/red|green|blue|yellow/,

208

String,

209

(s: string) => s.toUpperCase(),

210

true,

211

false

212

);

213

214

const registry = new ParameterTypeRegistry();

215

registry.defineParameterType(colorType);

216

217

// Use in expression

218

const expr = new CucumberExpression('I have a {color} ball', registry);

219

const args = expr.match('I have a red ball');

220

console.log(args?.[0].getValue()); // "RED"

221

222

// Custom type with capture groups

223

const coordinateType = new ParameterType(

224

'coordinate',

225

/(-?\d+),(-?\d+)/,

226

Object,

227

(x: string, y: string) => ({ x: parseInt(x), y: parseInt(y) }),

228

true,

229

false

230

);

231

232

registry.defineParameterType(coordinateType);

233

234

const coordExpr = new CucumberExpression('I am at {coordinate}', registry);

235

const coordArgs = coordExpr.match('I am at 10,-5');

236

console.log(coordArgs?.[0].getValue()); // { x: 10, y: -5 }

237

```

238

239

### Parameter Type Registry

240

241

Central registry for managing parameter types with lookup and definition capabilities.

242

243

```typescript { .api }

244

/**

245

* Registry for managing parameter types

246

*/

247

class ParameterTypeRegistry implements DefinesParameterType {

248

/**

249

* Create a new parameter type registry with built-in types

250

*/

251

constructor();

252

253

/** Iterator over all registered parameter types */

254

readonly parameterTypes: IterableIterator<ParameterType<unknown>>;

255

256

/**

257

* Look up a parameter type by name

258

* @param typeName - Name of the parameter type

259

* @returns Parameter type or undefined if not found

260

*/

261

lookupByTypeName(typeName: string): ParameterType<unknown> | undefined;

262

263

/**

264

* Look up parameter type by regular expression pattern

265

* @param parameterTypeRegexp - Regular expression to match

266

* @param expressionRegexp - Full expression regexp

267

* @param text - Text being matched

268

* @returns Matching parameter type or undefined

269

*/

270

lookupByRegexp(

271

parameterTypeRegexp: string,

272

expressionRegexp: RegExp,

273

text: string

274

): ParameterType<unknown> | undefined;

275

276

/**

277

* Register a new parameter type

278

* @param parameterType - Parameter type to register

279

*/

280

defineParameterType(parameterType: ParameterType<unknown>): void;

281

}

282

283

/**

284

* Interface for objects that can define parameter types

285

*/

286

interface DefinesParameterType {

287

defineParameterType<T>(parameterType: ParameterType<T>): void;

288

}

289

```

290

291

### Expression Factory

292

293

Factory for creating expressions from strings or regular expressions.

294

295

```typescript { .api }

296

/**

297

* Factory for creating expressions

298

*/

299

class ExpressionFactory {

300

/**

301

* Create expression factory with parameter type registry

302

* @param parameterTypeRegistry - Registry for parameter types

303

*/

304

constructor(parameterTypeRegistry: ParameterTypeRegistry);

305

306

/**

307

* Create an expression from string or RegExp

308

* @param expression - Expression string or regular expression

309

* @returns Expression instance (CucumberExpression or RegularExpression)

310

*/

311

createExpression(expression: string | RegExp): Expression;

312

}

313

```

314

315

**Usage Examples:**

316

317

```typescript

318

import { ExpressionFactory, ParameterTypeRegistry } from '@cucumber/cucumber-expressions';

319

320

const registry = new ParameterTypeRegistry();

321

const factory = new ExpressionFactory(registry);

322

323

// Create Cucumber expression

324

const cucumberExpr = factory.createExpression('I have {int} cucumbers');

325

console.log(cucumberExpr instanceof CucumberExpression); // true

326

327

// Create regular expression

328

const regexExpr = factory.createExpression(/^I have (\d+) cucumbers$/);

329

console.log(regexExpr instanceof RegularExpression); // true

330

```

331

332

### Expression Generation

333

334

Generate Cucumber expressions from example text for automated step definition creation.

335

336

```typescript { .api }

337

/**

338

* Generates Cucumber expressions from example text

339

*/

340

class CucumberExpressionGenerator {

341

/**

342

* Create generator with parameter types

343

* @param parameterTypes - Function returning iterable of parameter types

344

*/

345

constructor(parameterTypes: () => Iterable<ParameterType<unknown>>);

346

347

/**

348

* Generate expressions from example text

349

* @param text - Example text to generate expressions from

350

* @returns Array of generated expressions

351

*/

352

generateExpressions(text: string): readonly GeneratedExpression[];

353

}

354

355

/**

356

* Generated expression with metadata

357

*/

358

class GeneratedExpression {

359

/**

360

* Create generated expression

361

* @param expressionTemplate - Template string with parameter placeholders

362

* @param parameterTypes - Array of parameter types in order

363

*/

364

constructor(

365

expressionTemplate: string,

366

parameterTypes: readonly ParameterType<unknown>[]

367

);

368

369

/** The generated expression source */

370

readonly source: string;

371

372

/** Parameter names in order */

373

readonly parameterNames: readonly string[];

374

375

/** Parameter information */

376

readonly parameterInfos: readonly ParameterInfo[];

377

378

/** Parameter types in order */

379

readonly parameterTypes: readonly ParameterType<unknown>[];

380

}

381

382

/**

383

* Parameter information for code generation

384

*/

385

interface ParameterInfo {

386

/** Parameter type name */

387

type: string | null;

388

/** Parameter name for code generation */

389

name: string;

390

/** Number of occurrences */

391

count: number;

392

}

393

```

394

395

**Usage Examples:**

396

397

```typescript

398

import { CucumberExpressionGenerator, ParameterTypeRegistry } from '@cucumber/cucumber-expressions';

399

400

const registry = new ParameterTypeRegistry();

401

const generator = new CucumberExpressionGenerator(() => registry.parameterTypes);

402

403

// Generate from text with numbers

404

const expressions1 = generator.generateExpressions('I have 42 cucumbers');

405

console.log(expressions1[0].source); // "I have {int} cucumbers"

406

407

// Generate from text with quoted strings

408

const expressions2 = generator.generateExpressions('I have "many" cucumbers');

409

console.log(expressions2[0].source); // "I have {string} cucumbers"

410

411

// Generate from complex text

412

const expressions3 = generator.generateExpressions('User john has 5 apples and 3.5 oranges');

413

expressions3.forEach(expr => {

414

console.log(expr.source);

415

console.log(expr.parameterTypes.map(pt => pt.name));

416

});

417

```

418

419

### Argument Extraction

420

421

Extract and transform matched arguments from expressions.

422

423

```typescript { .api }

424

/**

425

* Represents a matched argument from an expression

426

*/

427

class Argument {

428

/**

429

* Create argument with group and parameter type

430

* @param group - Matched group from regex

431

* @param parameterType - Parameter type for transformation

432

*/

433

constructor(group: Group, parameterType: ParameterType<unknown>);

434

435

/**

436

* Build arguments from matched groups

437

* @param group - Root group from match

438

* @param parameterTypes - Parameter types for transformation

439

* @returns Array of arguments

440

*/

441

static build(group: Group, parameterTypes: readonly ParameterType<unknown>[]): readonly Argument[];

442

443

/** The matched group */

444

readonly group: Group;

445

446

/** The parameter type */

447

readonly parameterType: ParameterType<unknown>;

448

449

/**

450

* Get the transformed value

451

* @param thisObj - Context object for transformation

452

* @returns Transformed value or null

453

*/

454

getValue<T>(thisObj: unknown): T | null;

455

456

/**

457

* Get the parameter type

458

* @returns Parameter type

459

*/

460

getParameterType(): ParameterType<unknown>;

461

}

462

463

/**

464

* Represents a matched group from regex matching

465

*/

466

interface Group {

467

/** Matched text value */

468

value: string | null;

469

/** Start position in source text */

470

start: number;

471

/** End position in source text */

472

end: number;

473

/** Child groups */

474

children: Group[];

475

}

476

```

477

478

### Regular Expression Support

479

480

Support for traditional regular expressions alongside Cucumber expressions.

481

482

```typescript { .api }

483

/**

484

* Regular expression implementation of Expression interface

485

*/

486

class RegularExpression implements Expression {

487

/**

488

* Create regular expression

489

* @param regexp - Regular expression pattern

490

* @param parameterTypeRegistry - Registry for parameter types

491

*/

492

constructor(regexp: RegExp, parameterTypeRegistry: ParameterTypeRegistry);

493

494

/** The regular expression */

495

readonly regexp: RegExp;

496

497

/** The source pattern */

498

readonly source: string;

499

500

/**

501

* Match text against regular expression

502

* @param text - Text to match

503

* @returns Array of arguments or null if no match

504

*/

505

match(text: string): readonly Argument[] | null;

506

}

507

```

508

509

## AST Support

510

511

Abstract Syntax Tree representation for advanced expression manipulation.

512

513

```typescript { .api }

514

/**

515

* AST node representing parsed expression components

516

*/

517

interface Node {

518

/** Node type identifier */

519

type: NodeType;

520

/** Child nodes */

521

nodes?: Node[];

522

/** Associated token */

523

token?: Token;

524

/** Get text representation */

525

text(): string;

526

}

527

528

/**

529

* Token from lexical analysis

530

*/

531

interface Token {

532

/** Token type */

533

type: TokenType;

534

/** Token text */

535

text: string;

536

/** Start position */

537

start: number;

538

/** End position */

539

end: number;

540

}

541

542

/**

543

* AST node types

544

*/

545

enum NodeType {

546

text = 'text',

547

optional = 'optional',

548

alternation = 'alternation',

549

alternative = 'alternative',

550

parameter = 'parameter',

551

expression = 'expression'

552

}

553

554

/**

555

* Token types from lexer

556

*/

557

enum TokenType {

558

START_OF_LINE = 'START_OF_LINE',

559

END_OF_LINE = 'END_OF_LINE',

560

WHITE_SPACE = 'WHITE_SPACE',

561

BEGIN_PARAMETER = 'BEGIN_PARAMETER',

562

END_PARAMETER = 'END_PARAMETER',

563

BEGIN_OPTIONAL = 'BEGIN_OPTIONAL',

564

END_OPTIONAL = 'END_OPTIONAL',

565

BEGIN_ALTERNATION = 'BEGIN_ALTERNATION',

566

END_ALTERNATION = 'END_ALTERNATION',

567

ALTERNATION_PIPE = 'ALTERNATION_PIPE',

568

TEXT = 'TEXT'

569

}

570

```

571

572

## Built-in Parameter Types

573

574

The JavaScript/TypeScript implementation includes comprehensive built-in parameter types:

575

576

- `{int}` - 32-bit signed integers

577

- `{float}` - 32-bit floating point numbers

578

- `{word}` - Single words without whitespace

579

- `{string}` - Quoted strings (single or double quotes)

580

- `{bigdecimal}` - High-precision decimal numbers

581

- `{double}` - 64-bit floating point numbers

582

- `{biginteger}` - Arbitrary precision integers

583

- `{byte}` - 8-bit signed integers

584

- `{short}` - 16-bit signed integers

585

- `{long}` - 64-bit signed integers

586

- `{}` (anonymous) - Matches any text

587

588

All built-in types support appropriate JavaScript type conversion and error handling.