@ptolemy2002/rgx 4.11.0 → 5.1.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 +47 -23
- package/dist/class/base.d.ts +6 -6
- package/dist/class/base.js +6 -6
- package/dist/class/group.d.ts +1 -1
- package/dist/class/group.js +1 -1
- package/dist/class/index.d.ts +1 -0
- package/dist/class/index.js +1 -0
- package/dist/class/init.js +2 -2
- package/dist/class/lookaround.d.ts +2 -2
- package/dist/class/lookaround.js +2 -2
- package/dist/class/repeat.d.ts +3 -2
- package/dist/class/repeat.js +31 -18
- package/dist/class/subpattern.d.ts +13 -0
- package/dist/class/subpattern.js +43 -0
- package/dist/class/wrapper.d.ts +2 -2
- package/dist/class/wrapper.js +4 -4
- package/dist/typeGuards.js +7 -3
- package/dist/types.d.ts +8 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,12 +12,12 @@ import { CloneDepth } from "@ptolemy2002/immutability-utils";
|
|
|
12
12
|
type RGXNoOpToken = null | undefined;
|
|
13
13
|
type RGXLiteralToken = RegExp;
|
|
14
14
|
type RGXNativeToken = string | number | boolean | RGXNoOpToken;
|
|
15
|
-
type RGXConvertibleToken = { toRgx: () => RGXToken, readonly rgxGroupWrap?: boolean };
|
|
15
|
+
type RGXConvertibleToken = { toRgx: () => RGXToken, readonly rgxGroupWrap?: boolean, readonly rgxIsGroup?: boolean, readonly rgxIsRepeatable?: boolean };
|
|
16
16
|
type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
|
|
17
17
|
|
|
18
18
|
type RGXClassTokenConstructor = new (...args: unknown[]) => RGXClassToken;
|
|
19
|
-
type RGXGroupedToken = RGXToken[] | RGXLiteralToken |
|
|
20
|
-
type RGXGroupedConvertibleToken = { toRgx: () => RGXGroupedToken, readonly rgxGroupWrap: true
|
|
19
|
+
type RGXGroupedToken = RGXToken[] | RGXLiteralToken | RGXGroupedConvertibleToken;
|
|
20
|
+
type RGXGroupedConvertibleToken = (RGXConvertibleToken & { readonly rgxIsGroup: true }) | (Omit<RGXConvertibleToken, "toRGX"> & { toRgx: () => RGXGroupedToken, readonly rgxGroupWrap: true });
|
|
21
21
|
|
|
22
22
|
const validRegexSymbol = Symbol('rgx.ValidRegex');
|
|
23
23
|
type ValidRegexBrandSymbol = typeof validRegexSymbol;
|
|
@@ -39,7 +39,7 @@ type ValidIdentifier = Branded<string, [ValidIdentifierBrandSymbol]>;
|
|
|
39
39
|
|
|
40
40
|
type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | 'class' | RGXTokenType[];
|
|
41
41
|
type RGXTokenTypeFlat = Exclude<RGXTokenType, RGXTokenType[]> | "array";
|
|
42
|
-
type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
|
|
42
|
+
type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof RegExp | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
|
|
43
43
|
type RGXTokenFromType<T extends RGXTokenTypeGuardInput> =
|
|
44
44
|
// Maps token type strings to their corresponding types, e.g.:
|
|
45
45
|
// 'no-op' -> RGXNoOpToken, 'literal' -> RGXLiteralToken, etc.
|
|
@@ -279,15 +279,15 @@ An abstract base class for creating custom RGX token classes. Subclasses must im
|
|
|
279
279
|
- `clone(depth: CloneDepth = "max") => RGXClassToken`: Must be implemented by subclasses to return a deep clone of the token instance. The `depth` parameter controls how deeply nested tokens are cloned: `0` for no clone, `1` for a shallow clone of the top-level token, any other number for that many levels down, and `"max"` (the default) for a full deep clone.
|
|
280
280
|
|
|
281
281
|
#### Properties
|
|
282
|
-
- `
|
|
283
|
-
- `
|
|
282
|
+
- `rgxIsGroup` (`boolean`): Returns `false` by default. Subclasses can override this to indicate whether the token represents a group.
|
|
283
|
+
- `rgxIsRepeatable` (`boolean`): Returns `true` by default. Subclasses can override this to indicate that the token cannot be wrapped in an `RGXRepeatToken`. When `false`, attempting to set this token as the `token` property of an `RGXRepeatToken` (including via `repeat()` or `optional()`) will throw an `RGXNotSupportedError`.
|
|
284
284
|
- `rgxGroupWrap` (`boolean`): Returns `true` by default. Controls whether the resolver wraps this token's resolved output in a non-capturing group. Subclasses can override this to prevent double-wrapping (e.g., when the token already wraps itself in a group).
|
|
285
285
|
|
|
286
286
|
#### Methods
|
|
287
287
|
- `or(...others: RGXTokenCollectionInput[]) => RGXClassUnionToken`: Creates an `RGXClassUnionToken` that represents a union (alternation) of this token with the provided others. If any of the `others` are `RGXClassUnionToken` instances, their tokens are flattened into the union rather than nested. If `this` is already an `RGXClassUnionToken`, its existing tokens are preserved and the others are appended.
|
|
288
288
|
- `group(args?: RGXGroupTokenArgs) => RGXGroupToken`: Wraps this token in an `RGXGroupToken` with the provided arguments. The `args` parameter defaults to `{}`, which creates a capturing group with no name. This is a convenience method that creates a new `RGXGroupToken` with `this` as the sole token.
|
|
289
|
-
- `repeat(min?: number, max?: number | null) => RGXRepeatToken`: Wraps this token in an `RGXRepeatToken` with the given repetition bounds. `min` defaults to `1`, `max` defaults to `min`. Pass `null` for `max` to allow unlimited repetitions. This is a convenience method that creates a new `RGXRepeatToken` with `this` as the token. Throws `RGXNotSupportedError` if called on
|
|
290
|
-
- `optional() => RGXRepeatToken`: Shorthand for `repeat(0, 1)`. Wraps this token in an `RGXRepeatToken` that matches the token zero or one times. Throws `RGXNotSupportedError` if called on
|
|
289
|
+
- `repeat(min?: number, max?: number | null, lazy?: boolean) => RGXRepeatToken`: Wraps this token in an `RGXRepeatToken` with the given repetition bounds. `min` defaults to `1`, `max` defaults to `min`, `lazy` defaults to `false`. Pass `null` for `max` to allow unlimited repetitions. When `lazy` is `true`, the resulting quantifier will be non-greedy. This is a convenience method that creates a new `RGXRepeatToken` with `this` as the token. Throws `RGXNotSupportedError` if called on a token with `rgxIsRepeatable` set to `false` (e.g., `RGXLookaroundToken`).
|
|
290
|
+
- `optional(lazy?: boolean) => RGXRepeatToken`: Shorthand for `repeat(0, 1, lazy)`. Wraps this token in an `RGXRepeatToken` that matches the token zero or one times. `lazy` defaults to `false`. Throws `RGXNotSupportedError` if called on a token with `rgxIsRepeatable` set to `false` (e.g., `RGXLookaroundToken`).
|
|
291
291
|
- `asLookahead(positive?: boolean) => RGXLookaheadToken`: Wraps this token in an `RGXLookaheadToken`. `positive` defaults to `true`. If this token is already an `RGXLookaheadToken`, it is returned as-is without re-wrapping.
|
|
292
292
|
- `asLookbehind(positive?: boolean) => RGXLookbehindToken`: Wraps this token in an `RGXLookbehindToken`. `positive` defaults to `true`. If this token is already an `RGXLookbehindToken`, it is returned as-is without re-wrapping.
|
|
293
293
|
- `resolve() => ValidRegexString`: A convenience method that resolves this token by calling `resolveRGXToken(this)`, returning the resolved regex string representation. Since this method is defined on `RGXClassToken`, it is available on all subclasses including `RGXClassUnionToken`, `RGXGroupToken`, `RGXRepeatToken`, and `RGXLookaroundToken`.
|
|
@@ -337,7 +337,7 @@ constructor(args?: RGXGroupTokenArgs, tokens?: RGXTokenCollectionInput)
|
|
|
337
337
|
- `tokens` (`RGXTokenCollection`): The internal collection of tokens managed in 'concat' mode.
|
|
338
338
|
- `name` (`string | null`): The name of the group. Setting this to a non-null value validates it as a valid identifier via `assertValidIdentifier`.
|
|
339
339
|
- `capturing` (`boolean`): Whether the group is capturing. Any named group is automatically capturing (returns `true` when `name` is not `null`). Setting this to `false` also clears `name` to `null`.
|
|
340
|
-
- `
|
|
340
|
+
- `rgxIsGroup` (`true`): Returns `true` as a constant, indicating this token represents a group.
|
|
341
341
|
- `rgxGroupWrap` (`false`): Returns `false` as a constant, since the group already wraps itself, preventing the resolver from double-wrapping.
|
|
342
342
|
|
|
343
343
|
#### Methods
|
|
@@ -354,17 +354,19 @@ A function `rgxRepeat` is provided with the same parameters as this class' const
|
|
|
354
354
|
|
|
355
355
|
#### Constructor
|
|
356
356
|
```typescript
|
|
357
|
-
constructor(token: RGXToken, min?: number, max?: number | null)
|
|
357
|
+
constructor(token: RGXToken, min?: number, max?: number | null, lazy?: boolean)
|
|
358
358
|
```
|
|
359
359
|
- `token` (`RGXToken`): The token to repeat. If the token is not already a grouped token, it will be automatically wrapped in a non-capturing `RGXGroupToken`.
|
|
360
360
|
- `min` (`number`, optional): The minimum number of repetitions. Must be >= 0 and <= `max` (when `max` is not `null`). Non-integer values are floored. Defaults to `1`.
|
|
361
361
|
- `max` (`number | null`, optional): The maximum number of repetitions. Must be >= `min` when not `null`. Non-integer values are floored. Pass `null` for unlimited repetitions. Defaults to `min`.
|
|
362
|
+
- `lazy` (`boolean`, optional): Whether the quantifier should be non-greedy (lazy). Defaults to `false`.
|
|
362
363
|
|
|
363
364
|
#### Properties
|
|
364
|
-
- `token` (`RGXGroupedToken`): The token being repeated. Setting this will throw `RGXNotSupportedError` if the value is a
|
|
365
|
+
- `token` (`RGXGroupedToken`): The token being repeated. Setting this will throw `RGXNotSupportedError` if the value is a convertible token with `rgxIsRepeatable` set to `false`, and will automatically wrap non-grouped tokens in a non-capturing `RGXGroupToken`.
|
|
365
366
|
- `min` (`number`): The minimum number of repetitions. Setting this validates that the value is >= 0 and <= `max` (when `max` is not `null`), and floors non-integer values. Throws `RGXOutOfBoundsError` if validation fails.
|
|
366
367
|
- `max` (`number | null`): The maximum number of repetitions. Setting this validates that the value is >= `min` when not `null`, and floors non-integer values. Pass `null` for unlimited. Throws `RGXOutOfBoundsError` if validation fails.
|
|
367
|
-
- `
|
|
368
|
+
- `lazy` (`boolean`): Whether the quantifier is non-greedy (lazy). When `true`, a `?` is appended to the `repeaterSuffix` (except when the suffix is `?` or empty, since those cases don't benefit from a lazy modifier). Defaults to `false`.
|
|
369
|
+
- `repeaterSuffix` (`string`): Returns the regex quantifier suffix based on the current `min`, `max`, and `lazy` values: `*` for `{0,}`, `+` for `{1,}`, `?` for `{0,1}`, `{n}` for exact repetitions, `{n,}` for minimum-only, `{n,m}` for a range, or an empty string for `{1,1}` (exactly once, no quantifier needed). When `lazy` is `true`, a `?` is appended to the suffix (e.g., `*?`, `+?`, `{2,5}?`), except when the suffix is already `?` or empty.
|
|
368
370
|
- `rgxGroupWrap` (`false`): Returns `false` as a constant, since the quantifier suffix binds tightly to the preceding group and does not need additional wrapping.
|
|
369
371
|
|
|
370
372
|
#### Methods
|
|
@@ -388,8 +390,8 @@ constructor(tokens?: RGXTokenCollectionInput, positive?: boolean)
|
|
|
388
390
|
- `tokens` (`RGXTokenCollection`): The internal collection of tokens managed in 'concat' mode.
|
|
389
391
|
- `positive` (`boolean`): Whether the lookaround is positive. Setting this updates `negative` accordingly.
|
|
390
392
|
- `negative` (`boolean`): Whether the lookaround is negative. Setting this updates `positive` accordingly.
|
|
391
|
-
- `
|
|
392
|
-
- `
|
|
393
|
+
- `rgxIsGroup` (`true`): Returns `true` as a constant, indicating this token represents a group.
|
|
394
|
+
- `rgxIsRepeatable` (`false`): Returns `false` as a constant, since lookaround assertions cannot be repeated.
|
|
393
395
|
- `rgxGroupWrap` (`false`): Returns `false` as a constant, since the lookaround already wraps itself in a group.
|
|
394
396
|
|
|
395
397
|
#### Abstract Methods
|
|
@@ -424,8 +426,30 @@ A function `rgxLookbehind` is provided with the same parameters as this class' c
|
|
|
424
426
|
- `reverse() => RGXLookaheadToken`: Returns a new `RGXLookaheadToken` with the same tokens and positivity.
|
|
425
427
|
- `toRgx() => RegExp`: Resolves the lookbehind to a `RegExp`. Positive lookbehinds produce `(?<=...)` and negative lookbehinds produce `(?<!...)`.
|
|
426
428
|
|
|
429
|
+
### RGXSubpatternToken extends RGXClassToken
|
|
430
|
+
A class representing a backreference to a previously captured group, either by name or by group number. Named backreferences produce `\k<name>` and numbered backreferences produce `\N` (where N is the group number). This is useful for matching the same text that was captured by a previous group.
|
|
431
|
+
|
|
432
|
+
A function `rgxSubpattern` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
433
|
+
|
|
434
|
+
#### Static Properties
|
|
435
|
+
- `check(value: unknown): value is RGXSubpatternToken`: A type guard that checks if the given value is an instance of `RGXSubpatternToken`.
|
|
436
|
+
- `assert(value: unknown): asserts value is RGXSubpatternToken`: An assertion that checks if the given value is an instance of `RGXSubpatternToken`. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
|
|
437
|
+
|
|
438
|
+
#### Constructor
|
|
439
|
+
```typescript
|
|
440
|
+
constructor(pattern: string | number)
|
|
441
|
+
```
|
|
442
|
+
- `pattern` (`string | number`): The backreference pattern. If a string, it must be a valid identifier (validated via `assertValidIdentifier`) and produces a named backreference (`\k<name>`). If a number, it must be a positive integer (>= 1, as groups are 1-indexed) and produces a numbered backreference (`\N`). Non-integer numbers are floored.
|
|
443
|
+
|
|
444
|
+
#### Properties
|
|
445
|
+
- `pattern` (`string | number`): The backreference pattern. Setting this validates the value: strings must be valid identifiers, numbers must be positive integers (>= 1). Non-integer numbers are floored.
|
|
446
|
+
|
|
447
|
+
#### Methods
|
|
448
|
+
- `toRgx() => RegExp`: Resolves the backreference to a `RegExp`. Named patterns produce `/\k<name>/` and numbered patterns produce `/\N/`.
|
|
449
|
+
- `clone(depth: CloneDepth = "max") => RGXSubpatternToken`: Creates a clone of this token. When `depth` is `0`, returns `this`; otherwise, returns a new `RGXSubpatternToken` with the same pattern.
|
|
450
|
+
|
|
427
451
|
### RGXClassWrapperToken extends RGXClassToken
|
|
428
|
-
A class that wraps any `RGXToken` as an `RGXClassToken`, giving you access to the extended API class tokens provide. It delegates `
|
|
452
|
+
A class that wraps any `RGXToken` as an `RGXClassToken`, giving you access to the extended API class tokens provide. It delegates `rgxIsGroup` and `rgxIsRepeatable` to the wrapped token where possible.
|
|
429
453
|
|
|
430
454
|
A function `rgxClassWrapper` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
431
455
|
|
|
@@ -441,8 +465,8 @@ constructor(token: RGXToken)
|
|
|
441
465
|
|
|
442
466
|
#### Properties
|
|
443
467
|
- `token` (`RGXToken`): The wrapped token.
|
|
444
|
-
- `
|
|
445
|
-
- `
|
|
468
|
+
- `rgxIsGroup` (`boolean`): Delegates to the wrapped token's group status via `isRGXGroupedToken`. Returns `true` if the wrapped token is a grouped token, otherwise `false`.
|
|
469
|
+
- `rgxIsRepeatable` (`boolean`): If the wrapped token is an `RGXConvertibleToken`, delegates to its `rgxIsRepeatable` property (defaulting to `true` if not present). Otherwise, returns `true`.
|
|
446
470
|
|
|
447
471
|
#### Methods
|
|
448
472
|
- `unwrap() => RGXToken`: Returns the original wrapped token.
|
|
@@ -552,7 +576,7 @@ Asserts that the given value is a native token (string, number, boolean, or no-o
|
|
|
552
576
|
function isRGXConvertibleToken(value: unknown, returnCheck?: boolean): value is RGXConvertibleToken
|
|
553
577
|
```
|
|
554
578
|
|
|
555
|
-
Checks if the given value is a convertible token (an object with a `toRgx` method). If the `rgxGroupWrap`
|
|
579
|
+
Checks if the given value is a convertible token (an object with a `toRgx` method). If the `rgxGroupWrap`, `rgxIsRepeatable`, or `rgxIsGroup` properties are present, they must be booleans; otherwise, the check fails. When `returnCheck` is `true` (the default), also validates that `toRgx` is callable and returns a valid `RGXToken` (which can be any RGX token type, including other convertible tokens, allowing for recursive structures).
|
|
556
580
|
|
|
557
581
|
#### Parameters
|
|
558
582
|
- `value` (`unknown`): The value to check.
|
|
@@ -565,7 +589,7 @@ Checks if the given value is a convertible token (an object with a `toRgx` metho
|
|
|
565
589
|
```typescript
|
|
566
590
|
function assertRGXConvertibleToken(value: unknown, returnCheck?: boolean): asserts value is RGXConvertibleToken
|
|
567
591
|
```
|
|
568
|
-
Asserts that the given value is a convertible token (an object with a `toRgx` method). If the `rgxGroupWrap`
|
|
592
|
+
Asserts that the given value is a convertible token (an object with a `toRgx` method). If the `rgxGroupWrap`, `rgxIsRepeatable`, or `rgxIsGroup` properties are present, they must be booleans; otherwise, the assertion fails. When `returnCheck` is `true` (the default), also validates that `toRgx` is callable and returns a valid `RGXToken` (which can be any RGX token type, including other convertible tokens, allowing for recursive structures). If the assertion fails, an `RGXInvalidTokenError` will be thrown.
|
|
569
593
|
|
|
570
594
|
#### Parameters
|
|
571
595
|
- `value` (`unknown`): The value to assert.
|
|
@@ -701,7 +725,7 @@ function isRGXToken<T extends RGXTokenTypeGuardInput = null>(value: unknown, typ
|
|
|
701
725
|
|
|
702
726
|
Checks if the given value is a valid RGX token, optionally narrowed to a specific token type. When `type` is `null` (the default), it checks against all token types. When `type` is a specific token type string, it checks only against that type. The `'class'` type matches `RGXClassToken` instances specifically, while `'convertible'` also matches class tokens since they implement the convertible interface.
|
|
703
727
|
|
|
704
|
-
When `type` is
|
|
728
|
+
When `type` is a constructor, it performs an `instanceof` check against that specific constructor, allowing you to narrow to a specific class token subclass rather than all class tokens. In this case, `RGXTokenFromType` resolves to `InstanceType<T>`, giving you the specific subclass type.
|
|
705
729
|
|
|
706
730
|
When `type` is an array, it checks that every element of the value array is a valid RGX token matching the corresponding type in the `type` array. If `matchLength` is `true` (the default), it also requires that the value array has the same length as the type array; if `false`, it allows the value array to be longer than the type array, as long as all elements up to the length of the type array match and all elements after that are still valid RGX tokens of any type.
|
|
707
731
|
|
|
@@ -733,11 +757,11 @@ Asserts that the given value is a valid RGX token, optionally narrowed to a spec
|
|
|
733
757
|
function isRGXGroupedToken(value: unknown, contentCheck?: boolean): value is RGXGroupedToken
|
|
734
758
|
```
|
|
735
759
|
|
|
736
|
-
Checks if the given value is a grouped token — a token that is implicitly or explicitly a group. Arrays and literal tokens (`RegExp`) are implicitly groups.
|
|
760
|
+
Checks if the given value is a grouped token — a token that is implicitly or explicitly a group. Arrays and literal tokens (`RegExp`) are implicitly groups. Convertible tokens (including class tokens) are groups if they have `rgxIsGroup` set to `true`, or if they have `rgxGroupWrap` set to `true` and their `toRgx()` method returns a grouped token.
|
|
737
761
|
|
|
738
762
|
#### Parameters
|
|
739
763
|
- `value` (`unknown`): The value to check.
|
|
740
|
-
- `contentCheck` (`boolean`, optional): Whether to validate the contents of array tokens and the return values of convertible tokens. Defaults to `true`. When `false`, arrays are accepted without checking their elements, and convertible tokens with `rgxGroupWrap` set to `true` are accepted without checking their `toRgx()` return value.
|
|
764
|
+
- `contentCheck` (`boolean`, optional): Whether to validate the contents of array tokens and the return values of convertible tokens. Defaults to `true`. When `false`, arrays are accepted without checking their elements, and convertible tokens with `rgxGroupWrap` set to `true` are accepted without checking their `toRgx()` return value. This has no effect on the `rgxIsGroup` check, which always accepts the token as grouped regardless of `contentCheck`.
|
|
741
765
|
|
|
742
766
|
#### Returns
|
|
743
767
|
- `boolean`: `true` if the value is a grouped token, otherwise `false`.
|
|
@@ -751,7 +775,7 @@ Asserts that the given value is a grouped token. Uses the same logic as `isRGXGr
|
|
|
751
775
|
|
|
752
776
|
#### Parameters
|
|
753
777
|
- `value` (`unknown`): The value to assert.
|
|
754
|
-
- `contentCheck` (`boolean`, optional): Whether to validate the contents of array tokens and the return values of convertible tokens. Defaults to `true`. When `false`, arrays are accepted without checking their elements, and convertible tokens with `rgxGroupWrap` set to `true` are accepted without checking their `toRgx()` return value.
|
|
778
|
+
- `contentCheck` (`boolean`, optional): Whether to validate the contents of array tokens and the return values of convertible tokens. Defaults to `true`. When `false`, arrays are accepted without checking their elements, and convertible tokens with `rgxGroupWrap` set to `true` are accepted without checking their `toRgx()` return value. This has no effect on the `rgxIsGroup` check, which always accepts the token as grouped regardless of `contentCheck`.
|
|
755
779
|
|
|
756
780
|
#### Returns
|
|
757
781
|
- `void`: This function does not return a value, but will throw an error if the assertion fails.
|
package/dist/class/base.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RGXToken, ValidRegexString } from "../types";
|
|
1
|
+
import { RGXConvertibleToken, RGXToken, ValidRegexString } from "../types";
|
|
2
2
|
import { RGXTokenCollectionInput } from "../collection";
|
|
3
3
|
import { CloneDepth } from "@ptolemy2002/immutability-utils";
|
|
4
4
|
import type { RGXClassUnionToken } from "./union";
|
|
@@ -6,18 +6,18 @@ import type { RGXGroupToken, RGXGroupTokenArgs } from "./group";
|
|
|
6
6
|
import type { RGXRepeatToken } from "./repeat";
|
|
7
7
|
import type { RGXLookaheadToken } from "./lookahead";
|
|
8
8
|
import type { RGXLookbehindToken } from "./lookbehind";
|
|
9
|
-
export declare abstract class RGXClassToken {
|
|
9
|
+
export declare abstract class RGXClassToken implements RGXConvertibleToken {
|
|
10
10
|
abstract toRgx(): RGXToken;
|
|
11
11
|
abstract clone(depth?: CloneDepth): ThisType<this>;
|
|
12
12
|
static check: (value: unknown) => value is RGXClassToken;
|
|
13
13
|
static assert: (value: unknown) => asserts value is RGXClassToken;
|
|
14
|
-
get
|
|
15
|
-
get
|
|
14
|
+
get rgxIsGroup(): boolean;
|
|
15
|
+
get rgxIsRepeatable(): boolean;
|
|
16
16
|
get rgxGroupWrap(): boolean;
|
|
17
17
|
or(...others: RGXTokenCollectionInput[]): RGXClassUnionToken;
|
|
18
18
|
group(args?: RGXGroupTokenArgs): RGXGroupToken;
|
|
19
|
-
repeat(min?: number, max?: number | null): RGXRepeatToken;
|
|
20
|
-
optional(): RGXRepeatToken;
|
|
19
|
+
repeat(min?: number, max?: number | null, lazy?: boolean): RGXRepeatToken;
|
|
20
|
+
optional(lazy?: boolean): RGXRepeatToken;
|
|
21
21
|
asLookahead(positive?: boolean): RGXLookaheadToken;
|
|
22
22
|
asLookbehind(positive?: boolean): RGXLookbehindToken;
|
|
23
23
|
resolve(): ValidRegexString;
|
package/dist/class/base.js
CHANGED
|
@@ -4,10 +4,10 @@ exports.RGXClassToken = void 0;
|
|
|
4
4
|
const errors_1 = require("../errors");
|
|
5
5
|
const resolve_1 = require("../resolve");
|
|
6
6
|
class RGXClassToken {
|
|
7
|
-
get
|
|
7
|
+
get rgxIsGroup() {
|
|
8
8
|
return false;
|
|
9
9
|
}
|
|
10
|
-
get
|
|
10
|
+
get rgxIsRepeatable() {
|
|
11
11
|
return true;
|
|
12
12
|
}
|
|
13
13
|
get rgxGroupWrap() {
|
|
@@ -19,11 +19,11 @@ class RGXClassToken {
|
|
|
19
19
|
group(args = {}) {
|
|
20
20
|
throw new errors_1.RGXNotImplementedError('RGXClassToken.group(args)', 'call rgxClassInit() first.');
|
|
21
21
|
}
|
|
22
|
-
repeat(min = 1, max = min) {
|
|
23
|
-
throw new errors_1.RGXNotImplementedError('RGXClassToken.repeat(min, max)', 'call rgxClassInit() first.');
|
|
22
|
+
repeat(min = 1, max = min, lazy = false) {
|
|
23
|
+
throw new errors_1.RGXNotImplementedError('RGXClassToken.repeat(min, max, lazy)', 'call rgxClassInit() first.');
|
|
24
24
|
}
|
|
25
|
-
optional() {
|
|
26
|
-
return this.repeat(0, 1);
|
|
25
|
+
optional(lazy = false) {
|
|
26
|
+
return this.repeat(0, 1, lazy);
|
|
27
27
|
}
|
|
28
28
|
asLookahead(positive = true) {
|
|
29
29
|
throw new errors_1.RGXNotImplementedError('RGXClassToken.asLookahead(positive)', 'call rgxClassInit() first.');
|
package/dist/class/group.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare class RGXGroupToken extends RGXClassToken {
|
|
|
15
15
|
set name(value: string | null);
|
|
16
16
|
get capturing(): boolean;
|
|
17
17
|
set capturing(value: boolean);
|
|
18
|
-
get
|
|
18
|
+
get rgxIsGroup(): true;
|
|
19
19
|
get rgxGroupWrap(): false;
|
|
20
20
|
constructor({ name, capturing }?: RGXGroupTokenArgs, tokens?: RGXTokenCollectionInput);
|
|
21
21
|
toRgx(): RegExp;
|
package/dist/class/group.js
CHANGED
package/dist/class/index.d.ts
CHANGED
package/dist/class/index.js
CHANGED
|
@@ -23,4 +23,5 @@ __exportStar(require("./lookaround"), exports);
|
|
|
23
23
|
__exportStar(require("./lookahead"), exports);
|
|
24
24
|
__exportStar(require("./lookbehind"), exports);
|
|
25
25
|
__exportStar(require("./wrapper"), exports);
|
|
26
|
+
__exportStar(require("./subpattern"), exports);
|
|
26
27
|
__exportStar(require("./toRGXClassToken"), exports);
|
package/dist/class/init.js
CHANGED
|
@@ -28,10 +28,10 @@ function rgxClassInit() {
|
|
|
28
28
|
base_1.RGXClassToken.prototype.group = function (args = {}) {
|
|
29
29
|
return new group_1.RGXGroupToken(args, [this]);
|
|
30
30
|
};
|
|
31
|
-
base_1.RGXClassToken.prototype.repeat = function (min = 1, max = min) {
|
|
31
|
+
base_1.RGXClassToken.prototype.repeat = function (min = 1, max = min, lazy = false) {
|
|
32
32
|
if (lookaround_1.RGXLookaroundToken.check(this))
|
|
33
33
|
throw new errors_1.RGXNotSupportedError("RGXLookaroundToken.repeat()", "Lookaround tokens cannot be repeated or made optional.");
|
|
34
|
-
return new repeat_1.RGXRepeatToken(this, min, max);
|
|
34
|
+
return new repeat_1.RGXRepeatToken(this, min, max, lazy);
|
|
35
35
|
};
|
|
36
36
|
base_1.RGXClassToken.prototype.asLookahead = function (positive = true) {
|
|
37
37
|
if (lookahead_1.RGXLookaheadToken.check(this))
|
|
@@ -5,8 +5,8 @@ export declare abstract class RGXLookaroundToken extends RGXClassToken {
|
|
|
5
5
|
_negative: boolean;
|
|
6
6
|
static check: (value: unknown) => value is RGXLookaroundToken;
|
|
7
7
|
static assert: (value: unknown) => asserts value is RGXLookaroundToken;
|
|
8
|
-
get
|
|
9
|
-
get
|
|
8
|
+
get rgxIsGroup(): true;
|
|
9
|
+
get rgxIsRepeatable(): false;
|
|
10
10
|
get rgxGroupWrap(): false;
|
|
11
11
|
set negative(value: boolean);
|
|
12
12
|
get negative(): boolean;
|
package/dist/class/lookaround.js
CHANGED
|
@@ -5,10 +5,10 @@ const collection_1 = require("../collection");
|
|
|
5
5
|
const base_1 = require("./base");
|
|
6
6
|
const errors_1 = require("../errors");
|
|
7
7
|
class RGXLookaroundToken extends base_1.RGXClassToken {
|
|
8
|
-
get
|
|
8
|
+
get rgxIsGroup() {
|
|
9
9
|
return true;
|
|
10
10
|
}
|
|
11
|
-
get
|
|
11
|
+
get rgxIsRepeatable() {
|
|
12
12
|
return false;
|
|
13
13
|
}
|
|
14
14
|
get rgxGroupWrap() {
|
package/dist/class/repeat.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ export declare class RGXRepeatToken extends RGXClassToken {
|
|
|
5
5
|
_token: RGXGroupedToken;
|
|
6
6
|
_min: number;
|
|
7
7
|
_max: number | null;
|
|
8
|
+
lazy: boolean;
|
|
8
9
|
static check: (value: unknown) => value is RGXRepeatToken;
|
|
9
10
|
static assert: (value: unknown) => asserts value is RGXRepeatToken;
|
|
10
11
|
get min(): number;
|
|
@@ -14,9 +15,9 @@ export declare class RGXRepeatToken extends RGXClassToken {
|
|
|
14
15
|
get token(): RGXGroupedToken;
|
|
15
16
|
set token(value: RGXToken);
|
|
16
17
|
get rgxGroupWrap(): false;
|
|
17
|
-
constructor(token: RGXToken, min?: number, max?: number | null);
|
|
18
|
+
constructor(token: RGXToken, min?: number, max?: number | null, lazy?: boolean);
|
|
18
19
|
get repeaterSuffix(): string;
|
|
19
20
|
toRgx(): RGXToken;
|
|
20
21
|
clone(depth?: CloneDepth): RGXRepeatToken;
|
|
21
22
|
}
|
|
22
|
-
export declare const rgxRepeat: (token: RGXToken, min?: number | undefined, max?: number | null | undefined) => RGXRepeatToken;
|
|
23
|
+
export declare const rgxRepeat: (token: RGXToken, min?: number | undefined, max?: number | null | undefined, lazy?: boolean | undefined) => RGXRepeatToken;
|
package/dist/class/repeat.js
CHANGED
|
@@ -32,8 +32,13 @@ class RGXRepeatToken extends base_1.RGXClassToken {
|
|
|
32
32
|
return this._token;
|
|
33
33
|
}
|
|
34
34
|
set token(value) {
|
|
35
|
-
if ((0, typeGuards_1.isRGXToken)(value, "
|
|
36
|
-
|
|
35
|
+
if ((0, typeGuards_1.isRGXToken)(value, "convertible") && !value.rgxIsRepeatable) {
|
|
36
|
+
if ((0, typeGuards_1.isRGXToken)(value, "class")) {
|
|
37
|
+
throw new errors_1.RGXNotSupportedError(`Repeating ${value.constructor.name} tokens`, "The token was manually marked as non-repeatable.");
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
throw new errors_1.RGXNotSupportedError("Repeating tokens with {rgxIsRepeatable: false}", "The token was manually marked as non-repeatable.");
|
|
41
|
+
}
|
|
37
42
|
}
|
|
38
43
|
// Make sure we are always working with a grouped token.
|
|
39
44
|
if ((0, typeGuards_1.isRGXGroupedToken)(value))
|
|
@@ -47,29 +52,37 @@ class RGXRepeatToken extends base_1.RGXClassToken {
|
|
|
47
52
|
return false;
|
|
48
53
|
}
|
|
49
54
|
// By default, repeat a fixed number of times.
|
|
50
|
-
constructor(token, min = 1, max = min) {
|
|
55
|
+
constructor(token, min = 1, max = min, lazy = false) {
|
|
51
56
|
super();
|
|
52
57
|
this._max = null;
|
|
58
|
+
this.lazy = false;
|
|
53
59
|
this.token = token;
|
|
54
60
|
this.min = min;
|
|
55
61
|
this.max = max;
|
|
62
|
+
this.lazy = lazy;
|
|
56
63
|
}
|
|
57
64
|
get repeaterSuffix() {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
65
|
+
const result = (() => {
|
|
66
|
+
if (this.min === 0 && this.max === null)
|
|
67
|
+
return '*';
|
|
68
|
+
if (this.min === 1 && this.max === null)
|
|
69
|
+
return '+';
|
|
70
|
+
if (this.min === 0 && this.max === 1)
|
|
71
|
+
return '?';
|
|
72
|
+
if (this.max === null)
|
|
73
|
+
return `{${this.min},}`;
|
|
74
|
+
if (this.min === this.max) {
|
|
75
|
+
// No need for a repeater suffix if we're repeating exactly once.
|
|
76
|
+
if (this.min === 1)
|
|
77
|
+
return '';
|
|
78
|
+
return `{${this.min}}`;
|
|
79
|
+
}
|
|
80
|
+
return `{${this.min},${this.max}}`;
|
|
81
|
+
})();
|
|
82
|
+
if (this.lazy && result.length > 0 && result !== "?")
|
|
83
|
+
return result + '?';
|
|
84
|
+
else
|
|
85
|
+
return result;
|
|
73
86
|
}
|
|
74
87
|
toRgx() {
|
|
75
88
|
// No-op if we're repeating zero times.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RGXClassToken } from "./base";
|
|
2
|
+
import { CloneDepth } from "@ptolemy2002/immutability-utils";
|
|
3
|
+
export declare class RGXSubpatternToken extends RGXClassToken {
|
|
4
|
+
_pattern: string | number;
|
|
5
|
+
get pattern(): string | number;
|
|
6
|
+
set pattern(value: string | number);
|
|
7
|
+
static check: (value: unknown) => value is RGXSubpatternToken;
|
|
8
|
+
static assert: (value: unknown) => asserts value is RGXSubpatternToken;
|
|
9
|
+
constructor(pattern: string | number);
|
|
10
|
+
toRgx(): RegExp;
|
|
11
|
+
clone(depth?: CloneDepth): RGXSubpatternToken;
|
|
12
|
+
}
|
|
13
|
+
export declare const rgxSubpattern: (pattern: string | number) => RGXSubpatternToken;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rgxSubpattern = exports.RGXSubpatternToken = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
const typeGuards_1 = require("../typeGuards");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
const internal_1 = require("../internal");
|
|
8
|
+
class RGXSubpatternToken extends base_1.RGXClassToken {
|
|
9
|
+
get pattern() {
|
|
10
|
+
return this._pattern;
|
|
11
|
+
}
|
|
12
|
+
set pattern(value) {
|
|
13
|
+
if (typeof value === "string") {
|
|
14
|
+
(0, typeGuards_1.assertValidIdentifier)(value);
|
|
15
|
+
this._pattern = value;
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
(0, errors_1.assertInRange)(value, { min: 1 }, "Subpattern group numbers must be positive integers (groups are 1-indexed).");
|
|
19
|
+
this._pattern = Math.floor(value);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
constructor(pattern) {
|
|
23
|
+
super();
|
|
24
|
+
this.pattern = pattern;
|
|
25
|
+
}
|
|
26
|
+
toRgx() {
|
|
27
|
+
if (typeof this.pattern === "string") {
|
|
28
|
+
return new RegExp(`\\k<${this.pattern}>`);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
return new RegExp(`\\${this.pattern}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
clone(depth = "max") {
|
|
35
|
+
if (depth === 0)
|
|
36
|
+
return this;
|
|
37
|
+
return new RGXSubpatternToken(this.pattern);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
exports.RGXSubpatternToken = RGXSubpatternToken;
|
|
41
|
+
RGXSubpatternToken.check = (0, internal_1.createClassGuardFunction)(RGXSubpatternToken);
|
|
42
|
+
RGXSubpatternToken.assert = (0, internal_1.createAssertClassGuardFunction)(RGXSubpatternToken);
|
|
43
|
+
exports.rgxSubpattern = (0, internal_1.createConstructFunction)(RGXSubpatternToken);
|
package/dist/class/wrapper.d.ts
CHANGED
|
@@ -6,8 +6,8 @@ export declare class RGXClassWrapperToken extends RGXClassToken {
|
|
|
6
6
|
static check: (value: unknown) => value is RGXClassWrapperToken;
|
|
7
7
|
static assert: (value: unknown) => asserts value is RGXClassWrapperToken;
|
|
8
8
|
constructor(token: RGXToken);
|
|
9
|
-
get
|
|
10
|
-
get
|
|
9
|
+
get rgxIsGroup(): boolean;
|
|
10
|
+
get rgxIsRepeatable(): boolean;
|
|
11
11
|
unwrap(): RGXToken;
|
|
12
12
|
toRgx(): RGXToken;
|
|
13
13
|
clone(depth?: CloneDepth): RGXClassWrapperToken;
|
package/dist/class/wrapper.js
CHANGED
|
@@ -11,12 +11,12 @@ class RGXClassWrapperToken extends base_1.RGXClassToken {
|
|
|
11
11
|
super();
|
|
12
12
|
this.token = token;
|
|
13
13
|
}
|
|
14
|
-
get
|
|
14
|
+
get rgxIsGroup() {
|
|
15
15
|
return (0, typeGuards_1.isRGXGroupedToken)(this.token);
|
|
16
16
|
}
|
|
17
|
-
get
|
|
18
|
-
if ((0, typeGuards_1.isRGXToken)(this.token, '
|
|
19
|
-
return this.token.
|
|
17
|
+
get rgxIsRepeatable() {
|
|
18
|
+
if ((0, typeGuards_1.isRGXToken)(this.token, 'convertible'))
|
|
19
|
+
return this.token.rgxIsRepeatable ?? true;
|
|
20
20
|
// Assume any other token is repeatable, since we don't know its implementation.
|
|
21
21
|
return true;
|
|
22
22
|
}
|
package/dist/typeGuards.js
CHANGED
|
@@ -91,9 +91,13 @@ function assertRGXNativeToken(value) {
|
|
|
91
91
|
}
|
|
92
92
|
function isRGXConvertibleToken(value, returnCheck = true) {
|
|
93
93
|
if (typeof value === 'object' && value !== null && 'toRgx' in value) {
|
|
94
|
-
// The rgxGroupWrap
|
|
94
|
+
// The rgxGroupWrap, rgxIsRepeatable, and rgxIsGroup properties are optional, but if they exist they must be booleans.
|
|
95
95
|
if ('rgxGroupWrap' in value && typeof value.rgxGroupWrap !== 'boolean')
|
|
96
96
|
return false;
|
|
97
|
+
if ('rgxIsRepeatable' in value && typeof value.rgxIsRepeatable !== 'boolean')
|
|
98
|
+
return false;
|
|
99
|
+
if ('rgxIsGroup' in value && typeof value.rgxIsGroup !== 'boolean')
|
|
100
|
+
return false;
|
|
97
101
|
if ((0, is_callable_1.default)(value.toRgx)) {
|
|
98
102
|
if (!returnCheck)
|
|
99
103
|
return true;
|
|
@@ -200,8 +204,8 @@ function isRGXGroupedToken(value, contentCheck = true) {
|
|
|
200
204
|
// Classes are only groups if they have the isGroup property set to true.
|
|
201
205
|
return (isRGXArrayToken(value, contentCheck) ||
|
|
202
206
|
isRGXToken(value, "literal") ||
|
|
203
|
-
(
|
|
204
|
-
|
|
207
|
+
(isRGXConvertibleToken(value, false) && (value.rgxIsGroup ||
|
|
208
|
+
(value.rgxGroupWrap === true && (!contentCheck || isRGXGroupedToken(value.toRgx()))))));
|
|
205
209
|
}
|
|
206
210
|
function assertRGXGroupedToken(value, contentCheck = true) {
|
|
207
211
|
if (!isRGXGroupedToken(value, contentCheck)) {
|
package/dist/types.d.ts
CHANGED
|
@@ -8,19 +8,21 @@ export type RGXNativeToken = string | number | boolean | RGXNoOpToken;
|
|
|
8
8
|
export type RGXConvertibleToken = {
|
|
9
9
|
toRgx: () => RGXToken;
|
|
10
10
|
readonly rgxGroupWrap?: boolean;
|
|
11
|
+
readonly rgxIsGroup?: boolean;
|
|
12
|
+
readonly rgxIsRepeatable?: boolean;
|
|
11
13
|
};
|
|
12
14
|
export type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
|
|
13
15
|
export type RGXClassTokenConstructor = new (...args: unknown[]) => RGXClassToken;
|
|
14
|
-
export type RGXGroupedToken = RGXToken[] | RGXLiteralToken |
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
export type RGXGroupedToken = RGXToken[] | RGXLiteralToken | RGXGroupedConvertibleToken;
|
|
17
|
+
export type RGXGroupedConvertibleToken = (RGXConvertibleToken & {
|
|
18
|
+
readonly rgxIsGroup: true;
|
|
19
|
+
}) | (Omit<RGXConvertibleToken, "toRGX"> & {
|
|
18
20
|
toRgx: () => RGXGroupedToken;
|
|
19
21
|
readonly rgxGroupWrap: true;
|
|
20
|
-
};
|
|
22
|
+
});
|
|
21
23
|
export type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | 'class' | RGXTokenType[];
|
|
22
24
|
export type RGXTokenTypeFlat = Exclude<RGXTokenType, RGXTokenType[]> | "array";
|
|
23
|
-
export type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
|
|
25
|
+
export type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof RegExp | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
|
|
24
26
|
export type RGXTokenFromType<T extends RGXTokenTypeGuardInput> = T extends null ? RGXToken : T extends 'no-op' ? RGXNoOpToken : T extends 'literal' ? RGXLiteralToken : T extends 'native' ? RGXNativeToken : T extends 'convertible' ? RGXConvertibleToken : T extends 'class' ? RGXClassToken : T extends 'array' ? RGXToken[] : T extends new (...args: unknown[]) => infer R ? R : T extends RGXTokenTypeGuardInput[] ? {
|
|
25
27
|
[K in keyof T]: T[K] extends RGXTokenTypeGuardInput ? RGXTokenFromType<T[K]> : never;
|
|
26
28
|
} : never;
|