@ptolemy2002/rgx 7.4.0 → 7.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -88,10 +88,12 @@ type RGXCapture<T = unknown> = {
88
88
  start: number;
89
89
  end: number;
90
90
  ownerId: string | null;
91
+ branch: number;
91
92
  };
92
93
 
93
94
  type RGXPartOptions<R, T=string> = {
94
95
  id: string;
96
+ rawTransform: (captured: string) => string;
95
97
  transform: (captured: string) => T;
96
98
  validate: (captured: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => boolean | string;
97
99
  beforeCapture: ((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null;
@@ -108,6 +110,10 @@ type RGXWalkerOptions<R> = {
108
110
  type RGXWOptions<R = unknown> = Omit<RGXWalkerOptions<R>, "startingSourcePosition"> & {
109
111
  multiline?: boolean;
110
112
  };
113
+
114
+ // See src/constants.ts for the actual mapping of predefined constant names to their token values
115
+ type RGXPredefinedConstant = keyof typeof RGX_PREDEFINED_CONSTANTS;
116
+ type RGXConstantName = RGXPredefinedConstant | (string & {});
111
117
  ```
112
118
 
113
119
  ## Classes
@@ -622,6 +628,7 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
622
628
  - `token` (`RGXToken`): The token to wrap.
623
629
  - `options` (`Partial<RGXPartOptions<R, T>>`, optional): Configuration options. Defaults to `{}`.
624
630
  - `id` (`string`, optional): An optional identifier for this part. Defaults to `null`, but must be a string if provided.
631
+ - `rawTransform` (`(captured: string) => string`, optional): A function that transforms the raw captured string before it is stored as `raw` on the capture result and before `transform` is applied. Defaults to an identity function.
625
632
  - `transform` (`(captured: string) => T`, optional): A function that transforms the captured string into the desired type `T`. Defaults to an identity function that casts the string to `T`.
626
633
  - `beforeCapture` (`((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null`, optional): A callback invoked before capturing this part during walking. Returns an `RGXPartControl` value to control walker behavior: `"skip"` to skip this token without capturing, `"silent"` to capture but not record in `captures`, `"stop"` to halt immediately without capturing or advancing, or `void`/`undefined` to proceed normally. Defaults to `null`.
627
634
  - `afterCapture` (`((capture: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => void) | null`, optional): A callback invoked after capturing this part during walking. Receives the typed `RGXCapture<T>` result. Can call `walker.stop()` to halt walking after this capture. Defaults to `null`.
@@ -630,6 +637,7 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
630
637
  #### Properties
631
638
  - `id` (`string | null`): An optional identifier for this part.
632
639
  - `token` (`RGXToken`): The wrapped token.
640
+ - `rawTransform` (`(captured: string) => string`, readonly): The raw transform function applied to the matched string before it is stored as `raw` and before `transform` is called.
633
641
  - `transform` (`(captured: string) => T`, readonly): The transform function used to convert captured strings to values of type `T`.
634
642
  - `beforeCapture` (`((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null`, readonly): The before-capture callback, or `null`.
635
643
  - `afterCapture` (`((capture: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => void) | null`, readonly): The after-capture callback, or `null`.
@@ -638,7 +646,7 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
638
646
 
639
647
  #### Methods
640
648
  - `toRgx() => RGXToken`: Returns the wrapped token.
641
- - `clone(depth: CloneDepth = "max") => RGXPart`: Creates a clone of this part. When `depth` is `0`, returns `this`; otherwise, returns a new `RGXPart` with a cloned token and the same `transform`, `beforeCapture`, and `afterCapture` references.
649
+ - `clone(depth: CloneDepth = "max") => RGXPart`: Creates a clone of this part. When `depth` is `0`, returns `this`; otherwise, returns a new `RGXPart` with a cloned token and the same `rawTransform`, `transform`, `beforeCapture`, and `afterCapture` references.
642
650
  - `hasId() => this is RGXPart<R, T> & { id: string }`: A type guard that checks if this part has a non-null `id`. If `true`, narrows the type to indicate that `id` is a string.
643
651
  - `validate(capture: RGXCapture<T>, walker: RGXWalker<R>) => void`: A method that calls the inner passed validation logic for this part, if any. If it returns `false`, a generic `RGXPartValidationFailedError` is thrown. If it returns a string, an `RGXPartValidationFailedError` is thrown with that string as the message. If it returns `true`, validation passed. This is called internally by the walker after capturing and transforming a part, before invoking `afterCapture`.
644
652
 
@@ -669,14 +677,14 @@ constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalker
669
677
  - `tokens` (`RGXTokenCollection`): The internal collection of tokens in 'concat' mode (readonly).
670
678
  - `tokenPosition` (`number`): The current index in the token collection. Setting this validates that the value is >= 0 and <= `tokens.length`, throwing `RGXOutOfBoundsError` if not.
671
679
  - `reduced` (`R`): A user-defined accumulator value, typically updated by `RGXPart` callbacks during walking.
672
- - `captures` (`RGXCapture[]`): An array of structured capture results recorded during walking. Each entry has a `raw` string, a `value` (the transform result for Parts, or the raw string for plain tokens), `start` and `end` indices in the source string, and an `ownerId` that is the `id` of the Part that produced it (or `null` for captures from plain tokens or parts without ids).
680
+ - `captures` (`RGXCapture[]`): An array of structured capture results recorded during walking. Each entry has a `raw` string (the `rawTransform` result for Parts, or the matched string for plain tokens), a `value` (the `transform` result for Parts, or the matched string for plain tokens), `start` and `end` indices in the source string, an `ownerId` that is the `id` of the Part that produced it (or `null` for captures from plain tokens or parts without ids), and a `branch` index indicating which alternative of a multi-branch Part token was matched (or `0` if there is only one branch or the token is not a Part).
673
681
  - `namedCaptures` (`Record<string, RGXCapture[]>`): An object mapping capture IDs to their corresponding `RGXCapture` results. Only Parts with non-null IDs are included. The captures occur in the same order as they appear in the `captures` array.
674
682
  - `infinite` (`boolean`): Whether the walker is in infinite mode — stays at the last token when the token collection is exhausted until the source is consumed.
675
683
  - `looping` (`boolean`): Whether the walker is in looping mode — loops back to token position `0` when the token collection is exhausted until the source is consumed.
676
684
  - `stopped` (`boolean`, readonly): Whether the walker has been stopped, either by a Part's `beforeCapture` returning `"stop"` or by calling `stop()` in an `afterCapture` callback.
677
685
 
678
686
  #### Methods
679
- - `stop() => void`: Sets `stopped` to `true`, causing any active `stepToToken`, `stepToPart`, or `walk` loop to halt after the current iteration. Typically called from an `afterCapture` callback to stop walking after the current capture.
687
+ - `stop() => this`: Sets `stopped` to `true`, causing any active `stepToToken`, `stepToPart`, or `walk` loop to halt after the current iteration. Typically called from an `afterCapture` callback to stop walking after the current capture.
680
688
  - `atTokenEnd() => boolean`: Returns `true` if the token position is at or past the end of the token collection.
681
689
  - `hasNextToken(predicate?: (token: RGXToken) => boolean) => boolean`: Returns `true` if there is a current token and it satisfies the optional predicate (defaults to `() => true`).
682
690
  - `atSourceEnd() => boolean`: Returns `true` if the source has been fully consumed (`sourcePosition >= source.length`).
@@ -684,11 +692,12 @@ constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalker
684
692
  - `lastCapture() => RGXCapture | null`: Returns the last entry in `captures`, or `null` if empty.
685
693
  - `currentToken() => RGXToken | null`: Returns the token at the current token position, or `null` if at the end.
686
694
  - `remainingSource() => string | null`: Returns the remaining source string from the current position onward, or `null` if the source is fully consumed.
687
- - `capture(token: RGXToken) => string`: Resolves the token to a regex, asserts that it matches at the current source position (throwing `RGXRegexNotMatchedAtPositionError` if not), and advances the source position by the match length. Returns the matched string.
695
+ - `capture(token: RGXToken, includeMatch?: false) => string`: Resolves the token to a regex, asserts that it matches at the current source position (throwing `RGXRegexNotMatchedAtPositionError` if not), and advances the source position by the match length. Returns the matched string.
696
+ - `capture(token: RGXToken, includeMatch: true) => RegExpExecArray`: Same as above, but returns the full `RegExpExecArray` from the match instead of just the matched string.
688
697
  - `step() => RGXCapture | null`: Steps through the next token in the collection. If the token is an `RGXPart`, calls `beforeCapture` first — if it returns `"stop"`, sets `stopped` and returns `null` without advancing; if `"skip"`, advances the token position and returns `null` without capturing; if `"silent"`, captures but does not add to `captures` or `namedCaptures`. After capturing, validates. After validating, calls `afterCapture` if present. Returns the `RGXCapture` result, or `null` if there are no more tokens (or no more source in `infinite`/`looping` mode), the step was skipped, or the walker was stopped.
689
- - `stepToToken(predicate: (token: RGXToken) => boolean) => void`: Steps through tokens until the predicate returns `true` for the current token or the walker is stopped. The matching token is not consumed.
690
- - `stepToPart(predicate?: (part: RGXPart<R>) => boolean) => void`: Steps through tokens until the next `RGXPart` satisfying the predicate is reached. If already at a Part, steps once first to move past it. The matching Part is not consumed.
691
- - `walk() => void`: Steps through all remaining tokens until the end of the token collection (or until the source is consumed in `infinite`/`looping` mode) or the walker is stopped.
698
+ - `stepToToken(predicate: (token: RGXToken) => boolean) => this`: Steps through tokens until the predicate returns `true` for the current token or the walker is stopped. The matching token is not consumed.
699
+ - `stepToPart(predicate?: (part: RGXPart<R>) => boolean) => this`: Steps through tokens until the next `RGXPart` satisfying the predicate is reached. If already at a Part, steps once first to move past it. The matching Part is not consumed.
700
+ - `walk() => this`: Steps through all remaining tokens until the end of the token collection (or until the source is consumed in `infinite`/`looping` mode) or the walker is stopped.
692
701
  - `toRgx() => RGXToken`: Returns the internal `RGXTokenCollection`, allowing the walker to be used as a convertible token.
693
702
  - `clone(depth: CloneDepth = "max") => RGXWalker`: Creates a clone of the walker. When `depth` is `0`, returns `this`; otherwise, creates a new `RGXWalker` with cloned tokens, source position, reduced value, captures, stopped state, and the `infinite`/`looping` flags.
694
703
 
@@ -1480,49 +1489,58 @@ Creates a new `ExtRegExp` from an existing one with additional or replaced flags
1480
1489
 
1481
1490
  ### regexMatchAtPosition
1482
1491
  ```typescript
1483
- function regexMatchAtPosition(regex: RegExp, str: string, position: number): string | null
1492
+ function regexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch: true): RegExpExecArray | null
1493
+ function regexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch?: false): string | null
1484
1494
  ```
1485
1495
 
1486
- Attempts to match the given regular expression at a specific position in the string and returns the matched string, or `null` if there is no match. This is done by creating a sticky (`y` flag) copy of the regex and setting its `lastIndex` to the desired position. The position must be within the bounds of the string (>= 0 and < string length), or an `RGXOutOfBoundsError` will be thrown.
1496
+ Attempts to match the given regular expression at a specific position in the string. This is done by creating a sticky (`y` flag) copy of the regex and setting its `lastIndex` to the desired position. The position must be within the bounds of the string (>= 0 and < string length), or an `RGXOutOfBoundsError` will be thrown.
1487
1497
 
1488
1498
  #### Parameters
1489
1499
  - `regex` (`RegExp`): The regular expression to match.
1490
1500
  - `str` (`string`): The string to match against.
1491
1501
  - `position` (`number`): The zero-based index in the string at which to attempt the match. Must be >= 0 and < `str.length`.
1502
+ - `includeMatch` (`boolean`, optional): When `true`, returns the full `RegExpExecArray` instead of just the matched string. Defaults to `false`.
1492
1503
 
1493
1504
  #### Returns
1494
- - `string | null`: The matched string if the regex matches at the specified position, otherwise `null`.
1505
+ - `string | null`: When `includeMatch` is `false` (default): the matched string if the regex matches at the specified position, otherwise `null`.
1506
+ - `RegExpExecArray | null`: When `includeMatch` is `true`: the full match array if the regex matches, otherwise `null`.
1495
1507
 
1496
1508
  ### doesRegexMatchAtPosition
1497
1509
  ```typescript
1498
- function doesRegexMatchAtPosition(regex: RegExp, str: string, position: number): boolean
1510
+ function doesRegexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch: true): RegExpExecArray | false
1511
+ function doesRegexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch?: false): boolean
1499
1512
  ```
1500
1513
 
1501
- Tests whether the given regular expression matches at a specific position in the string. This is a boolean wrapper around `regexMatchAtPosition`, returning `true` if the match is non-null.
1514
+ Tests whether the given regular expression matches at a specific position in the string.
1502
1515
 
1503
1516
  #### Parameters
1504
1517
  - `regex` (`RegExp`): The regular expression to test.
1505
1518
  - `str` (`string`): The string to test against.
1506
1519
  - `position` (`number`): The zero-based index in the string at which to test the match. Must be >= 0 and < `str.length`.
1520
+ - `includeMatch` (`boolean`, optional): When `true`, returns the full `RegExpExecArray` on a match instead of `true`. Defaults to `false`.
1507
1521
 
1508
1522
  #### Returns
1509
- - `boolean`: `true` if the regex matches at the specified position, otherwise `false`.
1523
+ - `boolean`: When `includeMatch` is `false` (default): `true` if the regex matches at the specified position, otherwise `false`.
1524
+ - `RegExpExecArray | false`: When `includeMatch` is `true`: the full match array if the regex matches, otherwise `false`.
1510
1525
 
1511
1526
  ### assertRegexMatchesAtPosition
1512
1527
  ```typescript
1513
- function assertRegexMatchesAtPosition(regex: RegExp, str: string, position: number, contextSize?: number | null): string
1528
+ function assertRegexMatchesAtPosition(regex: RegExp, str: string, position: number, contextSize?: number | null, includeMatch?: false): string
1529
+ function assertRegexMatchesAtPosition(regex: RegExp, str: string, position: number, contextSize: number | null | undefined, includeMatch: true): RegExpExecArray
1514
1530
  ```
1515
1531
 
1516
- Asserts that the given regular expression matches at a specific position in the string, throwing an `RGXRegexNotMatchedAtPositionError` if it does not. On success, returns the matched string.
1532
+ Asserts that the given regular expression matches at a specific position in the string, throwing an `RGXRegexNotMatchedAtPositionError` if it does not. On success, returns the matched string or full match array depending on `includeMatch`.
1517
1533
 
1518
1534
  #### Parameters
1519
1535
  - `regex` (`RegExp`): The regular expression to match.
1520
1536
  - `str` (`string`): The string to match against.
1521
1537
  - `position` (`number`): The zero-based index in the string at which to assert the match. Must be >= 0 and < `str.length`.
1522
1538
  - `contextSize` (`number | null`, optional): The number of characters on each side of the position to include in the error's context output. Defaults to `10`.
1539
+ - `includeMatch` (`boolean`, optional): When `true`, returns the full `RegExpExecArray` instead of just the matched string. Defaults to `false`.
1523
1540
 
1524
1541
  #### Returns
1525
- - `string`: The matched string if the regex matches at the specified position. Throws `RGXRegexNotMatchedAtPositionError` if there is no match.
1542
+ - `string`: When `includeMatch` is `false` (default): the matched string. Throws `RGXRegexNotMatchedAtPositionError` if there is no match.
1543
+ - `RegExpExecArray`: When `includeMatch` is `true`: the full match array. Throws `RGXRegexNotMatchedAtPositionError` if there is no match.
1526
1544
 
1527
1545
  ### cloneRGXToken
1528
1546
  ```typescript
@@ -1537,6 +1555,13 @@ Creates a clone of the given RGX token to the given depth, provided that the tok
1537
1555
  #### Returns
1538
1556
  - `T`: The cloned token.
1539
1557
 
1558
+ ### RGX_PREDEFINED_CONSTANTS
1559
+ ```typescript
1560
+ const RGX_PREDEFINED_CONSTANTS: Record<RGXPredefinedConstant, RGXToken>
1561
+ ```
1562
+
1563
+ A read-only object containing all of the library's built-in constant definitions, keyed by their `RGXPredefinedConstant` name. This is the source from which the predefined constants are registered at module load time. It can be used to inspect available constant names at compile time (via `keyof typeof RGX_PREDEFINED_CONSTANTS`) or to iterate over the predefined set without calling `listRGXConstants`.
1564
+
1540
1565
  ### listRGXConstants
1541
1566
  ```typescript
1542
1567
  function listRGXConstants(): string[]
@@ -1549,52 +1574,52 @@ Returns the names of all currently defined RGX constants.
1549
1574
 
1550
1575
  ### hasRGXConstant
1551
1576
  ```typescript
1552
- function hasRGXConstant(name: string): boolean
1577
+ function hasRGXConstant(name: RGXConstantName): boolean
1553
1578
  ```
1554
1579
 
1555
1580
  Checks if an RGX constant with the given name exists.
1556
1581
 
1557
1582
  #### Parameters
1558
- - `name` (`string`): The constant name to check.
1583
+ - `name` (`RGXConstantName`): The constant name to check.
1559
1584
 
1560
1585
  #### Returns
1561
1586
  - `boolean`: `true` if the constant exists, otherwise `false`.
1562
1587
 
1563
1588
  ### assertHasRGXConstant
1564
1589
  ```typescript
1565
- function assertHasRGXConstant(name: string): void
1590
+ function assertHasRGXConstant(name: RGXConstantName): void
1566
1591
  ```
1567
1592
 
1568
1593
  Asserts that an RGX constant with the given name exists. If the assertion fails, an `RGXInvalidConstantKeyError` will be thrown.
1569
1594
 
1570
1595
  #### Parameters
1571
- - `name` (`string`): The constant name to assert.
1596
+ - `name` (`RGXConstantName`): The constant name to assert.
1572
1597
 
1573
1598
  #### Returns
1574
1599
  - `void`: This function does not return a value, but will throw an error if the assertion fails.
1575
1600
 
1576
1601
  ### assertNotHasRGXConstant
1577
1602
  ```typescript
1578
- function assertNotHasRGXConstant(name: string): void
1603
+ function assertNotHasRGXConstant(name: RGXConstantName): void
1579
1604
  ```
1580
1605
 
1581
1606
  Asserts that an RGX constant with the given name does not exist. If the assertion fails, an `RGXConstantConflictError` will be thrown.
1582
1607
 
1583
1608
  #### Parameters
1584
- - `name` (`string`): The constant name to assert.
1609
+ - `name` (`RGXConstantName`): The constant name to assert.
1585
1610
 
1586
1611
  #### Returns
1587
1612
  - `void`: This function does not return a value, but will throw an error if the assertion fails.
1588
1613
 
1589
1614
  ### defineRGXConstant
1590
1615
  ```typescript
1591
- function defineRGXConstant(name: string, value: RGXToken): RGXToken
1616
+ function defineRGXConstant(name: RGXConstantName, value: RGXToken): RGXToken
1592
1617
  ```
1593
1618
 
1594
1619
  Defines a new RGX constant with the given name and value. If the value is a native token (string, number, boolean, or no-op), it is automatically wrapped in an `RGXClassWrapperToken` before being stored. This ensures that native-valued constants are not stripped by multiline template processing in `rgx`, since only the literal string parts of the template are affected by multiline mode. Throws an `RGXConstantConflictError` if a constant with the same name already exists.
1595
1620
 
1596
1621
  #### Parameters
1597
- - `name` (`string`): The name for the constant.
1622
+ - `name` (`RGXConstantName`): The name for the constant.
1598
1623
  - `value` (`RGXToken`): The token value to associate with the name. Native tokens are automatically wrapped in `RGXClassWrapperToken`.
1599
1624
 
1600
1625
  #### Returns
@@ -1602,26 +1627,26 @@ Defines a new RGX constant with the given name and value. If the value is a nati
1602
1627
 
1603
1628
  ### rgxConstant
1604
1629
  ```typescript
1605
- function rgxConstant(name: string): RGXToken
1630
+ function rgxConstant(name: RGXConstantName): RGXToken
1606
1631
  ```
1607
1632
 
1608
1633
  Retrieves the value of an RGX constant by name. Throws an `RGXInvalidConstantKeyError` if no constant with the given name exists.
1609
1634
 
1610
1635
  #### Parameters
1611
- - `name` (`string`): The constant name to retrieve.
1636
+ - `name` (`RGXConstantName`): The constant name to retrieve.
1612
1637
 
1613
1638
  #### Returns
1614
1639
  - `RGXToken`: The token value associated with the constant name.
1615
1640
 
1616
1641
  ### deleteRGXConstant
1617
1642
  ```typescript
1618
- function deleteRGXConstant(name: string): void
1643
+ function deleteRGXConstant(name: RGXConstantName): void
1619
1644
  ```
1620
1645
 
1621
1646
  Deletes an existing RGX constant by name. Throws an `RGXInvalidConstantKeyError` if no constant with the given name exists.
1622
1647
 
1623
1648
  #### Parameters
1624
- - `name` (`string`): The constant name to delete.
1649
+ - `name` (`RGXConstantName`): The constant name to delete.
1625
1650
 
1626
1651
  #### Returns
1627
1652
  - `void`: This function does not return a value, but will throw an error if the constant does not exist.
@@ -1643,7 +1668,8 @@ Since these are defined as native tokens (strings), they are automatically wrapp
1643
1668
  ### Special Characters
1644
1669
  | Name | Resolves To | Description |
1645
1670
  | --- | --- | --- |
1646
- | `"any"` | `.` | Matches any single character (except newline by default) |
1671
+ | `"any"` | `(?s:.)` | Matches any single character, including newlines |
1672
+ | `"non-newline"` | `.` | Matches any single character except newlines |
1647
1673
  | `"start"` | `^` | Start of string anchor |
1648
1674
  | `"line-start"` | `^` (with `m` flag) | Start of line anchor |
1649
1675
  | `"end"` | `$` | End of string anchor |
@@ -1,8 +1,133 @@
1
1
  import { RGXToken } from "./types";
2
+ export declare const RGX_PREDEFINED_CONSTANTS: {
3
+ readonly newline: "\n";
4
+ readonly "carriage-return": "\r";
5
+ readonly tab: "\t";
6
+ readonly null: "\0";
7
+ readonly "form-feed": "\f";
8
+ readonly any: {
9
+ readonly rgxGroupWrap: false;
10
+ readonly toRgx: () => RegExp;
11
+ };
12
+ readonly "non-newline": {
13
+ readonly rgxGroupWrap: false;
14
+ readonly toRgx: () => RegExp;
15
+ };
16
+ readonly start: {
17
+ readonly rgxGroupWrap: false;
18
+ readonly rgxIsRepeatable: false;
19
+ readonly toRgx: () => RegExp;
20
+ };
21
+ readonly "line-start": {
22
+ readonly rgxGroupWrap: false;
23
+ readonly rgxIsRepeatable: false;
24
+ readonly toRgx: () => RegExp;
25
+ };
26
+ readonly end: {
27
+ readonly rgxGroupWrap: false;
28
+ readonly rgxIsRepeatable: false;
29
+ readonly toRgx: () => RegExp;
30
+ };
31
+ readonly "line-end": {
32
+ readonly rgxGroupWrap: false;
33
+ readonly rgxIsRepeatable: false;
34
+ readonly toRgx: () => RegExp;
35
+ };
36
+ readonly "word-bound": {
37
+ readonly rgxGroupWrap: false;
38
+ readonly rgxIsRepeatable: false;
39
+ readonly toRgx: () => RegExp;
40
+ };
41
+ readonly "non-word-bound": {
42
+ readonly rgxGroupWrap: false;
43
+ readonly rgxIsRepeatable: false;
44
+ readonly toRgx: () => RegExp;
45
+ };
46
+ readonly "word-bound-start": {
47
+ readonly rgxGroupWrap: false;
48
+ readonly rgxIsRepeatable: false;
49
+ readonly toRgx: () => RegExp;
50
+ };
51
+ readonly "word-bound-end": {
52
+ readonly rgxGroupWrap: false;
53
+ readonly rgxIsRepeatable: false;
54
+ readonly toRgx: () => RegExp;
55
+ };
56
+ readonly letter: {
57
+ readonly rgxIsGroup: true;
58
+ readonly rgxGroupWrap: false;
59
+ readonly toRgx: () => RegExp;
60
+ };
61
+ readonly "lowercase-letter": {
62
+ readonly rgxIsGroup: true;
63
+ readonly rgxGroupWrap: false;
64
+ readonly toRgx: () => RegExp;
65
+ };
66
+ readonly "uppercase-letter": {
67
+ readonly rgxIsGroup: true;
68
+ readonly rgxGroupWrap: false;
69
+ readonly toRgx: () => RegExp;
70
+ };
71
+ readonly "non-letter": {
72
+ readonly rgxIsGroup: true;
73
+ readonly rgxGroupWrap: false;
74
+ readonly toRgx: () => RegExp;
75
+ };
76
+ readonly alphanumeric: {
77
+ readonly rgxIsGroup: true;
78
+ readonly rgxGroupWrap: false;
79
+ readonly toRgx: () => RegExp;
80
+ };
81
+ readonly "non-alphanumeric": {
82
+ readonly rgxIsGroup: true;
83
+ readonly rgxGroupWrap: false;
84
+ readonly toRgx: () => RegExp;
85
+ };
86
+ readonly digit: {
87
+ readonly rgxGroupWrap: false;
88
+ readonly toRgx: () => RegExp;
89
+ };
90
+ readonly "non-digit": {
91
+ readonly rgxGroupWrap: false;
92
+ readonly toRgx: () => RegExp;
93
+ };
94
+ readonly whitespace: {
95
+ readonly rgxGroupWrap: false;
96
+ readonly toRgx: () => RegExp;
97
+ };
98
+ readonly "non-whitespace": {
99
+ readonly rgxGroupWrap: false;
100
+ readonly toRgx: () => RegExp;
101
+ };
102
+ readonly "vertical-whitespace": {
103
+ readonly rgxGroupWrap: false;
104
+ readonly toRgx: () => RegExp;
105
+ };
106
+ readonly "word-char": {
107
+ readonly rgxGroupWrap: false;
108
+ readonly toRgx: () => RegExp;
109
+ };
110
+ readonly "non-word-char": {
111
+ readonly rgxGroupWrap: false;
112
+ readonly toRgx: () => RegExp;
113
+ };
114
+ readonly backspace: {
115
+ readonly rgxIsGroup: true;
116
+ readonly rgxGroupWrap: false;
117
+ readonly toRgx: () => RegExp;
118
+ };
119
+ readonly "non-escape-bound": {
120
+ readonly rgxGroupWrap: false;
121
+ readonly rgxIsRepeatable: false;
122
+ readonly toRgx: () => RegExp;
123
+ };
124
+ };
125
+ export type RGXPredefinedConstant = keyof typeof RGX_PREDEFINED_CONSTANTS;
126
+ export type RGXConstantName = RGXPredefinedConstant | (string & {});
2
127
  export declare function listRGXConstants(): string[];
3
- export declare function hasRGXConstant(name: string): boolean;
4
- export declare function assertHasRGXConstant(name: string): void;
5
- export declare function assertNotHasRGXConstant(name: string): void;
6
- export declare function defineRGXConstant(name: string, value: RGXToken): RegExp | import("./types").RGXConvertibleToken | RGXToken[];
7
- export declare function rgxConstant(name: string): RGXToken;
8
- export declare function deleteRGXConstant(name: string): void;
128
+ export declare function hasRGXConstant(name: RGXConstantName): boolean;
129
+ export declare function assertHasRGXConstant(name: RGXConstantName): void;
130
+ export declare function assertNotHasRGXConstant(name: RGXConstantName): void;
131
+ export declare function defineRGXConstant(name: RGXConstantName, value: RGXToken): RegExp | import("./types").RGXConvertibleToken | RGXToken[];
132
+ export declare function rgxConstant(name: RGXConstantName): RGXToken;
133
+ export declare function deleteRGXConstant(name: RGXConstantName): void;
package/dist/constants.js CHANGED
@@ -1,5 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RGX_PREDEFINED_CONSTANTS = void 0;
3
4
  exports.listRGXConstants = listRGXConstants;
4
5
  exports.hasRGXConstant = hasRGXConstant;
5
6
  exports.assertHasRGXConstant = assertHasRGXConstant;
@@ -11,6 +12,143 @@ const class_1 = require("./class");
11
12
  const errors_1 = require("./errors");
12
13
  const typeGuards_1 = require("./typeGuards");
13
14
  const rgxConstants = {};
15
+ exports.RGX_PREDEFINED_CONSTANTS = {
16
+ // Control Characters
17
+ "newline": "\n",
18
+ "carriage-return": "\r",
19
+ "tab": "\t",
20
+ "null": "\0",
21
+ "form-feed": "\f",
22
+ // Special Characters
23
+ "any": {
24
+ rgxGroupWrap: false,
25
+ toRgx() { return /./s; }
26
+ },
27
+ "non-newline": {
28
+ rgxGroupWrap: false,
29
+ toRgx() { return /./; }
30
+ },
31
+ "start": {
32
+ rgxGroupWrap: false,
33
+ rgxIsRepeatable: false,
34
+ toRgx() { return /^/; }
35
+ },
36
+ "line-start": {
37
+ rgxGroupWrap: false,
38
+ rgxIsRepeatable: false,
39
+ toRgx() { return /^/m; }
40
+ },
41
+ "end": {
42
+ rgxGroupWrap: false,
43
+ rgxIsRepeatable: false,
44
+ toRgx() { return /$/; }
45
+ },
46
+ "line-end": {
47
+ rgxGroupWrap: false,
48
+ rgxIsRepeatable: false,
49
+ toRgx() { return /$/m; }
50
+ },
51
+ "word-bound": {
52
+ rgxGroupWrap: false,
53
+ rgxIsRepeatable: false,
54
+ toRgx() { return /\b/; }
55
+ },
56
+ "non-word-bound": {
57
+ rgxGroupWrap: false,
58
+ rgxIsRepeatable: false,
59
+ toRgx() { return /\B/; }
60
+ },
61
+ "word-bound-start": {
62
+ rgxGroupWrap: false,
63
+ rgxIsRepeatable: false,
64
+ toRgx() {
65
+ // Make sure there is a non-word character before and a word character after
66
+ return /(?<=\W)(?=\w)/;
67
+ }
68
+ },
69
+ "word-bound-end": {
70
+ rgxGroupWrap: false,
71
+ rgxIsRepeatable: false,
72
+ toRgx() {
73
+ // Make sure there is a word character before and a non-word character after
74
+ return /(?<=\w)(?=\W)/;
75
+ }
76
+ },
77
+ // Character Sets
78
+ "letter": {
79
+ rgxIsGroup: true,
80
+ rgxGroupWrap: false,
81
+ toRgx() { return /[a-zA-Z]/; }
82
+ },
83
+ "lowercase-letter": {
84
+ rgxIsGroup: true,
85
+ rgxGroupWrap: false,
86
+ toRgx() { return /[a-z]/; }
87
+ },
88
+ "uppercase-letter": {
89
+ rgxIsGroup: true,
90
+ rgxGroupWrap: false,
91
+ toRgx() { return /[A-Z]/; }
92
+ },
93
+ "non-letter": {
94
+ rgxIsGroup: true,
95
+ rgxGroupWrap: false,
96
+ toRgx() { return /[^a-zA-Z]/; }
97
+ },
98
+ "alphanumeric": {
99
+ rgxIsGroup: true,
100
+ rgxGroupWrap: false,
101
+ toRgx() { return /[a-zA-Z0-9]/; }
102
+ },
103
+ "non-alphanumeric": {
104
+ rgxIsGroup: true,
105
+ rgxGroupWrap: false,
106
+ toRgx() { return /[^a-zA-Z0-9]/; }
107
+ },
108
+ // Predefined Character Sets
109
+ "digit": {
110
+ rgxGroupWrap: false,
111
+ toRgx() { return /\d/; }
112
+ },
113
+ "non-digit": {
114
+ rgxGroupWrap: false,
115
+ toRgx() { return /\D/; }
116
+ },
117
+ "whitespace": {
118
+ rgxGroupWrap: false,
119
+ toRgx() { return /\s/; }
120
+ },
121
+ "non-whitespace": {
122
+ rgxGroupWrap: false,
123
+ toRgx() { return /\S/; }
124
+ },
125
+ "vertical-whitespace": {
126
+ rgxGroupWrap: false,
127
+ toRgx() { return /\v/; }
128
+ },
129
+ "word-char": {
130
+ rgxGroupWrap: false,
131
+ toRgx() { return /\w/; }
132
+ },
133
+ "non-word-char": {
134
+ rgxGroupWrap: false,
135
+ toRgx() { return /\W/; }
136
+ },
137
+ "backspace": {
138
+ rgxIsGroup: true,
139
+ rgxGroupWrap: false,
140
+ toRgx() { return /[\b]/; }
141
+ },
142
+ // Complex Constructs
143
+ "non-escape-bound": {
144
+ rgxGroupWrap: false,
145
+ rgxIsRepeatable: false,
146
+ toRgx() {
147
+ // Put this before any pattern to ensure that the pattern is not escaped, i.e., not preceded by an odd number of backslashes.
148
+ return /(?<=(?<!\\)(?:\\\\)*)(?=[^\\]|$)/;
149
+ }
150
+ },
151
+ };
14
152
  function listRGXConstants() {
15
153
  return Object.keys(rgxConstants);
16
154
  }
@@ -41,176 +179,6 @@ function deleteRGXConstant(name) {
41
179
  assertHasRGXConstant(name);
42
180
  delete rgxConstants[name];
43
181
  }
44
- // Control Characters
45
- defineRGXConstant("newline", "\n");
46
- defineRGXConstant("carriage-return", "\r");
47
- defineRGXConstant("tab", "\t");
48
- defineRGXConstant("null", "\0");
49
- defineRGXConstant("form-feed", "\f");
50
- // Special Characters
51
- defineRGXConstant("any", {
52
- rgxGroupWrap: false,
53
- toRgx() {
54
- return /./;
55
- }
56
- });
57
- defineRGXConstant("start", {
58
- rgxGroupWrap: false,
59
- rgxIsRepeatable: false,
60
- toRgx() {
61
- return /^/;
62
- }
63
- });
64
- defineRGXConstant("line-start", {
65
- rgxGroupWrap: false,
66
- rgxIsRepeatable: false,
67
- toRgx() {
68
- return /^/m;
69
- }
70
- });
71
- defineRGXConstant("end", {
72
- rgxGroupWrap: false,
73
- rgxIsRepeatable: false,
74
- toRgx() {
75
- return /$/;
76
- }
77
- });
78
- defineRGXConstant("line-end", {
79
- rgxGroupWrap: false,
80
- rgxIsRepeatable: false,
81
- toRgx() {
82
- return /$/m;
83
- }
84
- });
85
- defineRGXConstant("word-bound", {
86
- rgxGroupWrap: false,
87
- rgxIsRepeatable: false,
88
- toRgx() {
89
- return /\b/;
90
- }
91
- });
92
- defineRGXConstant("non-word-bound", {
93
- rgxGroupWrap: false,
94
- rgxIsRepeatable: false,
95
- toRgx() {
96
- return /\B/;
97
- }
98
- });
99
- defineRGXConstant("word-bound-start", {
100
- rgxGroupWrap: false,
101
- rgxIsRepeatable: false,
102
- toRgx() {
103
- // Make sure there is a non-word character before and a word character after
104
- return /(?<=\W)(?=\w)/;
105
- }
106
- });
107
- defineRGXConstant("word-bound-end", {
108
- rgxGroupWrap: false,
109
- rgxIsRepeatable: false,
110
- toRgx() {
111
- // Make sure there is a word character before and a non-word character after
112
- return /(?<=\w)(?=\W)/;
113
- }
114
- });
115
- // Character Sets
116
- defineRGXConstant("letter", {
117
- rgxIsGroup: true,
118
- rgxGroupWrap: false,
119
- toRgx() {
120
- return /[a-zA-Z]/;
121
- }
122
- });
123
- defineRGXConstant("lowercase-letter", {
124
- rgxIsGroup: true,
125
- rgxGroupWrap: false,
126
- toRgx() {
127
- return /[a-z]/;
128
- }
129
- });
130
- defineRGXConstant("uppercase-letter", {
131
- rgxIsGroup: true,
132
- rgxGroupWrap: false,
133
- toRgx() {
134
- return /[A-Z]/;
135
- }
136
- });
137
- defineRGXConstant("non-letter", {
138
- rgxIsGroup: true,
139
- rgxGroupWrap: false,
140
- toRgx() {
141
- return /[^a-zA-Z]/;
142
- }
143
- });
144
- defineRGXConstant("alphanumeric", {
145
- rgxIsGroup: true,
146
- rgxGroupWrap: false,
147
- toRgx() {
148
- return /[a-zA-Z0-9]/;
149
- }
150
- });
151
- defineRGXConstant("non-alphanumeric", {
152
- rgxIsGroup: true,
153
- rgxGroupWrap: false,
154
- toRgx() {
155
- return /[^a-zA-Z0-9]/;
156
- }
157
- });
158
- // Predefined Character Sets
159
- defineRGXConstant("digit", {
160
- rgxGroupWrap: false,
161
- toRgx() {
162
- return /\d/;
163
- }
164
- });
165
- defineRGXConstant("non-digit", {
166
- rgxGroupWrap: false,
167
- toRgx() {
168
- return /\D/;
169
- }
170
- });
171
- defineRGXConstant("whitespace", {
172
- rgxGroupWrap: false,
173
- toRgx() {
174
- return /\s/;
175
- }
176
- });
177
- defineRGXConstant("non-whitespace", {
178
- rgxGroupWrap: false,
179
- toRgx() {
180
- return /\S/;
181
- }
182
- });
183
- defineRGXConstant("vertical-whitespace", {
184
- rgxGroupWrap: false,
185
- toRgx() {
186
- return /\v/;
187
- }
188
- });
189
- defineRGXConstant("word-char", {
190
- rgxGroupWrap: false,
191
- toRgx() {
192
- return /\w/;
193
- }
194
- });
195
- defineRGXConstant("non-word-char", {
196
- rgxGroupWrap: false,
197
- toRgx() {
198
- return /\W/;
199
- }
200
- });
201
- defineRGXConstant("backspace", {
202
- rgxIsGroup: true,
203
- rgxGroupWrap: false,
204
- toRgx() {
205
- return /[\b]/;
206
- }
207
- });
208
- // Complex Constructs
209
- // Put this before any pattern to ensure that the pattern is not escaped, i.e., not preceded by an odd number of backslashes.
210
- defineRGXConstant("non-escape-bound", {
211
- rgxGroupWrap: false,
212
- rgxIsRepeatable: false,
213
- toRgx() {
214
- return /(?<=(?<!\\)(?:\\\\)*)(?=[^\\]|$)/;
215
- }
216
- });
182
+ for (const [name, value] of Object.entries(exports.RGX_PREDEFINED_CONSTANTS)) {
183
+ defineRGXConstant(name, value);
184
+ }
@@ -1,3 +1,6 @@
1
- export declare function regexMatchAtPosition(regex: RegExp, str: string, position: number): string | null;
2
- export declare function doesRegexMatchAtPosition(regex: RegExp, str: string, position: number): boolean;
3
- export declare function assertRegexMatchesAtPosition(regex: RegExp, str: string, position: number, contextSize?: number | null): string;
1
+ export declare function regexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch: true): RegExpExecArray | null;
2
+ export declare function regexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch?: false): string | null;
3
+ export declare function doesRegexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch: true): RegExpExecArray | false;
4
+ export declare function doesRegexMatchAtPosition(regex: RegExp, str: string, position: number, includeMatch?: false): boolean;
5
+ export declare function assertRegexMatchesAtPosition(regex: RegExp, str: string, position: number, contextSize?: number | null, includeMatch?: false): string;
6
+ export declare function assertRegexMatchesAtPosition(regex: RegExp, str: string, position: number, contextSize: number | null | undefined, includeMatch: true): RegExpExecArray;
@@ -6,7 +6,7 @@ exports.assertRegexMatchesAtPosition = assertRegexMatchesAtPosition;
6
6
  const outOfBounds_1 = require("../errors/outOfBounds");
7
7
  const regexWithFlags_1 = require("./regexWithFlags");
8
8
  const errors_1 = require("../errors");
9
- function regexMatchAtPosition(regex, str, position) {
9
+ function regexMatchAtPosition(regex, str, position, includeMatch = false) {
10
10
  /*
11
11
  The y flag means sticky mode, which means the next match must start at
12
12
  lastIndex. By setting lastIndex to the position we want to check, we can test
@@ -16,15 +16,18 @@ function regexMatchAtPosition(regex, str, position) {
16
16
  const stickyRegex = (0, regexWithFlags_1.regexWithFlags)(regex, "y");
17
17
  stickyRegex.lastIndex = position;
18
18
  const match = stickyRegex.exec(str);
19
- return match ? match[0] : null;
19
+ return includeMatch ? match : (match ? match[0] : null);
20
20
  }
21
- function doesRegexMatchAtPosition(regex, str, position) {
22
- return regexMatchAtPosition(regex, str, position) !== null;
21
+ function doesRegexMatchAtPosition(regex, str, position, includeMatch = false) {
22
+ const match = regexMatchAtPosition(regex, str, position, true);
23
+ if (includeMatch)
24
+ return match ?? false;
25
+ return match !== null;
23
26
  }
24
- function assertRegexMatchesAtPosition(regex, str, position, contextSize = 10) {
25
- const result = regexMatchAtPosition(regex, str, position);
27
+ function assertRegexMatchesAtPosition(regex, str, position, contextSize = 10, includeMatch = false) {
28
+ const result = regexMatchAtPosition(regex, str, position, true);
26
29
  if (result === null) {
27
30
  throw new errors_1.RGXRegexNotMatchedAtPositionError("Regex not matched at index", regex, str, position, contextSize);
28
31
  }
29
- return result;
32
+ return includeMatch ? result : result[0];
30
33
  }
@@ -27,7 +27,7 @@ export declare class RGXWalker<R> implements RGXConvertibleToken {
27
27
  set tokenPosition(value: number);
28
28
  get stopped(): boolean;
29
29
  constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalkerOptions<R>);
30
- stop(): void;
30
+ stop(): this;
31
31
  atTokenEnd(): boolean;
32
32
  hasNextToken(predicate?: (token: RGXToken) => boolean): boolean;
33
33
  atSourceEnd(): boolean;
@@ -35,11 +35,12 @@ export declare class RGXWalker<R> implements RGXConvertibleToken {
35
35
  lastCapture(): RGXCapture | null;
36
36
  currentToken(): RGXToken;
37
37
  remainingSource(): string | null;
38
- capture(token: RGXToken): string;
38
+ capture(token: RGXToken, includeMatch: true): RegExpExecArray;
39
+ capture(token: RGXToken, includeMatch?: false): string;
39
40
  step(): RGXCapture | null;
40
- stepToToken(predicate: (token: RGXToken) => boolean): void;
41
- stepToPart(predicate?: (part: RGXPart<R>) => boolean): void;
42
- walk(): void;
41
+ stepToToken(predicate: (token: RGXToken) => boolean): this;
42
+ stepToPart(predicate?: (part: RGXPart<R>) => boolean): this;
43
+ walk(): this;
43
44
  toRgx(): RGXTokenCollection;
44
45
  clone(depth?: CloneDepth): RGXWalker<R>;
45
46
  }
@@ -8,6 +8,20 @@ const errors_1 = require("../errors");
8
8
  const part_1 = require("./part");
9
9
  const index_1 = require("../index");
10
10
  const internal_1 = require("../internal");
11
+ function createBranchGroups(tokens) {
12
+ if ((tokens instanceof collection_1.RGXTokenCollection && tokens.mode === "union") ||
13
+ index_1.RGXClassUnionToken.check(tokens))
14
+ return createBranchGroups(tokens.tokens);
15
+ if ((0, index_1.isRGXArrayToken)(tokens)) {
16
+ const newTokens = tokens.map((token, i) => {
17
+ return new index_1.RGXGroupToken({ name: `rgx_branch_${i}` }, [token]);
18
+ });
19
+ return new index_1.RGXClassUnionToken(newTokens);
20
+ }
21
+ else {
22
+ return tokens;
23
+ }
24
+ }
11
25
  class RGXWalker {
12
26
  get sourcePosition() {
13
27
  return this._sourcePosition;
@@ -40,6 +54,7 @@ class RGXWalker {
40
54
  }
41
55
  stop() {
42
56
  this._stopped = true;
57
+ return this;
43
58
  }
44
59
  atTokenEnd() {
45
60
  return this.tokenPosition >= this.tokens.length;
@@ -68,11 +83,11 @@ class RGXWalker {
68
83
  return null;
69
84
  return this.source.slice(this.sourcePosition);
70
85
  }
71
- capture(token) {
86
+ capture(token, includeMatch = false) {
72
87
  const regex = (0, index_1.rgxa)([token]);
73
- const match = (0, index_1.assertRegexMatchesAtPosition)(regex, this.source, this.sourcePosition);
74
- this.sourcePosition += match.length;
75
- return match;
88
+ const match = (0, index_1.assertRegexMatchesAtPosition)(regex, this.source, this.sourcePosition, 10, true);
89
+ this.sourcePosition += match[0].length;
90
+ return includeMatch ? match : match[0];
76
91
  }
77
92
  step() {
78
93
  if (!this.infinite && !this.looping && this.atTokenEnd()) {
@@ -104,10 +119,26 @@ class RGXWalker {
104
119
  }
105
120
  // Capture the match
106
121
  const start = this.sourcePosition;
107
- const raw = this.capture(token);
122
+ let innerToken = token;
123
+ if (isPart)
124
+ innerToken = createBranchGroups(token.token);
125
+ const capture = this.capture(innerToken, true);
126
+ const raw = isPart ? token.rawTransform(capture[0]) : capture[0];
108
127
  const end = this.sourcePosition;
109
128
  const value = isPart ? token.transform(raw) : raw;
110
- const captureResult = { raw, value, start, end, ownerId: isPart && token.hasId() ? token.id : null };
129
+ let branch = 0;
130
+ if (isPart) {
131
+ // Determine branch index for captureResult by finding the first index
132
+ // with non-undefined match group.
133
+ for (let i = 0; i < capture.length; i++) {
134
+ const branchKey = `rgx_branch_${i}`;
135
+ if (capture.groups && capture.groups[branchKey] !== undefined) {
136
+ branch = i;
137
+ break;
138
+ }
139
+ }
140
+ }
141
+ const captureResult = { raw, value, start, end, branch, ownerId: isPart && token.hasId() ? token.id : null };
111
142
  // Validate the part. If validation fails, it will throw an error, so nothing below will run.
112
143
  if (isPart) {
113
144
  token.validate(captureResult, this);
@@ -142,6 +173,7 @@ class RGXWalker {
142
173
  if (this._stopped)
143
174
  break;
144
175
  }
176
+ return this;
145
177
  }
146
178
  stepToPart(predicate = () => true) {
147
179
  // If currently at a Part, step past it first so repeated
@@ -150,9 +182,10 @@ class RGXWalker {
150
182
  this._stopped = false;
151
183
  this.step();
152
184
  if (this._stopped)
153
- return;
185
+ return this;
154
186
  }
155
187
  this.stepToToken(token => token instanceof part_1.RGXPart && predicate(token));
188
+ return this;
156
189
  }
157
190
  walk() {
158
191
  return this.stepToToken(() => false);
@@ -8,9 +8,11 @@ export type RGXCapture<T = unknown> = {
8
8
  start: number;
9
9
  end: number;
10
10
  ownerId: string | null;
11
+ branch: number;
11
12
  };
12
13
  export type RGXPartOptions<R, T = string> = {
13
14
  id: string;
15
+ rawTransform: (captured: string) => string;
14
16
  transform: (captured: string) => T;
15
17
  validate: (captured: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => boolean | string;
16
18
  beforeCapture: ((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null;
@@ -19,6 +21,7 @@ export type RGXPartOptions<R, T = string> = {
19
21
  export declare class RGXPart<R, T = string> implements RGXConvertibleToken {
20
22
  id: string | null;
21
23
  token: RGXToken;
24
+ readonly rawTransform: RGXPartOptions<R, T>["rawTransform"];
22
25
  readonly transform: RGXPartOptions<R, T>["transform"];
23
26
  private readonly _validate;
24
27
  readonly beforeCapture: RGXPartOptions<R, T>["beforeCapture"];
@@ -11,6 +11,7 @@ class RGXPart {
11
11
  constructor(token, options = {}) {
12
12
  this.id = options.id ?? null;
13
13
  this.token = token;
14
+ this.rawTransform = options.rawTransform ?? (captured => captured);
14
15
  this.transform = options.transform ?? ((captured) => captured);
15
16
  this._validate = options.validate ?? (() => true);
16
17
  this.beforeCapture = options.beforeCapture ?? null;
@@ -45,6 +46,7 @@ class RGXPart {
45
46
  return this;
46
47
  return new RGXPart((0, clone_1.cloneRGXToken)(this.token, (0, immutability_utils_1.depthDecrement)(depth, 1)), {
47
48
  id: this.id ?? undefined,
49
+ rawTransform: this.rawTransform,
48
50
  transform: this.transform,
49
51
  beforeCapture: this.beforeCapture,
50
52
  afterCapture: this.afterCapture,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ptolemy2002/rgx",
3
- "version": "7.4.0",
3
+ "version": "7.6.0",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",