@ptolemy2002/rgx 4.7.0 → 4.10.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 +129 -10
- package/dist/class/base.d.ts +5 -0
- package/dist/class/base.js +9 -0
- package/dist/class/index.d.ts +5 -0
- package/dist/class/index.js +5 -0
- package/dist/class/init.js +16 -0
- package/dist/class/lookahead.d.ts +11 -0
- package/dist/class/lookahead.js +26 -0
- package/dist/class/lookaround.d.ts +18 -0
- package/dist/class/lookaround.js +47 -0
- package/dist/class/lookbehind.d.ts +12 -0
- package/dist/class/lookbehind.js +26 -0
- package/dist/class/repeat.js +3 -0
- package/dist/class/toRGXClassToken.d.ts +3 -0
- package/dist/class/toRGXClassToken.js +20 -0
- package/dist/class/wrapper.d.ts +13 -0
- package/dist/class/wrapper.js +31 -0
- package/dist/concat.d.ts +1 -1
- package/dist/concat.js +2 -2
- package/dist/errors/base.d.ts +1 -1
- package/dist/errors/index.d.ts +1 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/notSupported.d.ts +6 -0
- package/dist/errors/notSupported.js +19 -0
- package/dist/index.js +1 -1
- package/dist/resolve.d.ts +1 -1
- package/dist/resolve.js +30 -9
- package/dist/typeGuards.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -44,7 +44,7 @@ type RGXTokenFromType<T extends RGXTokenTypeGuardInput> =
|
|
|
44
44
|
// ... see source for full definition
|
|
45
45
|
;
|
|
46
46
|
|
|
47
|
-
type RGXErrorCode = 'UNKNOWN' | 'INVALID_RGX_TOKEN' | 'INVALID_REGEX_STRING' | 'INVALID_REGEX_FLAGS' | 'INVALID_VANILLA_REGEX_FLAGS' | 'NOT_IMPLEMENTED' | 'INVALID_IDENTIFIER' | 'OUT_OF_BOUNDS' | 'INVALID_FLAG_TRANSFORMER_KEY' | 'FLAG_TRANSFORMER_CONFLICT';
|
|
47
|
+
type RGXErrorCode = 'UNKNOWN' | 'INVALID_RGX_TOKEN' | 'INVALID_REGEX_STRING' | 'INVALID_REGEX_FLAGS' | 'INVALID_VANILLA_REGEX_FLAGS' | 'NOT_IMPLEMENTED' | 'NOT_SUPPORTED' | 'INVALID_IDENTIFIER' | 'OUT_OF_BOUNDS' | 'INVALID_FLAG_TRANSFORMER_KEY' | 'FLAG_TRANSFORMER_CONFLICT';
|
|
48
48
|
|
|
49
49
|
type RangeObject = {
|
|
50
50
|
min?: number | null;
|
|
@@ -143,6 +143,19 @@ constructor(functionality: string, message?: string | null)
|
|
|
143
143
|
#### Properties
|
|
144
144
|
- `functionality` (`string`): The description of the unimplemented functionality.
|
|
145
145
|
|
|
146
|
+
### RGXNotSupportedError extends RGXError
|
|
147
|
+
A specific error class for unsupported functionality. This error is thrown when a feature or method is intentionally not supported (as opposed to simply not yet implemented). The error code is set to `NOT_SUPPORTED` on instantiation.
|
|
148
|
+
|
|
149
|
+
#### Constructor
|
|
150
|
+
```typescript
|
|
151
|
+
constructor(functionality: string, message?: string | null)
|
|
152
|
+
```
|
|
153
|
+
- `functionality` (`string`): A description of the functionality that is not supported.
|
|
154
|
+
- `message` (`string | null`, optional): An optional additional message providing more context. Defaults to `null`.
|
|
155
|
+
|
|
156
|
+
#### Properties
|
|
157
|
+
- `functionality` (`string`): The description of the unsupported functionality.
|
|
158
|
+
|
|
146
159
|
### RGXInvalidIdentifierError extends RGXError
|
|
147
160
|
A specific error class for invalid identifiers. This error is thrown when a string fails validation as a valid identifier. The error code is set to `INVALID_IDENTIFIER` on instantiation.
|
|
148
161
|
|
|
@@ -262,14 +275,17 @@ An abstract base class for creating custom RGX token classes. Subclasses must im
|
|
|
262
275
|
|
|
263
276
|
#### Properties
|
|
264
277
|
- `isGroup` (`boolean`): Returns `false` by default. Subclasses can override this to indicate whether the token represents a group.
|
|
278
|
+
- `isRepeatable` (`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`.
|
|
265
279
|
- `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).
|
|
266
280
|
|
|
267
281
|
#### Methods
|
|
268
282
|
- `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.
|
|
269
283
|
- `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.
|
|
270
|
-
- `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.
|
|
271
|
-
- `optional() => RGXRepeatToken`: Shorthand for `repeat(0, 1)`. Wraps this token in an `RGXRepeatToken` that matches the token zero or one times.
|
|
272
|
-
- `
|
|
284
|
+
- `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 an `RGXLookaroundToken`, as lookaround assertions cannot be repeated.
|
|
285
|
+
- `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 an `RGXLookaroundToken`, as lookaround assertions cannot be made optional.
|
|
286
|
+
- `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.
|
|
287
|
+
- `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.
|
|
288
|
+
- `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`.
|
|
273
289
|
|
|
274
290
|
### RGXClassUnionToken extends RGXClassToken
|
|
275
291
|
A class representing a union (alternation) of RGX tokens. This is typically created via the `or()` method on `RGXClassToken`, but can also be instantiated directly.
|
|
@@ -340,7 +356,7 @@ constructor(token: RGXToken, min?: number, max?: number | null)
|
|
|
340
356
|
- `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`.
|
|
341
357
|
|
|
342
358
|
#### Properties
|
|
343
|
-
- `token` (`RGXGroupedToken`): The token being repeated. Setting this will automatically wrap non-grouped tokens in a non-capturing `RGXGroupToken`.
|
|
359
|
+
- `token` (`RGXGroupedToken`): The token being repeated. Setting this will throw `RGXNotSupportedError` if the value is a class token with `isRepeatable` set to `false`, and will automatically wrap non-grouped tokens in a non-capturing `RGXGroupToken`.
|
|
344
360
|
- `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.
|
|
345
361
|
- `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.
|
|
346
362
|
- `repeaterSuffix` (`string`): Returns the regex quantifier suffix based on the current `min` and `max` 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).
|
|
@@ -349,6 +365,84 @@ constructor(token: RGXToken, min?: number, max?: number | null)
|
|
|
349
365
|
#### Methods
|
|
350
366
|
- `toRgx() => RGXToken`: Resolves the repeat token to a `RegExp` by resolving the inner token and appending the `repeaterSuffix`. Returns `null` (a no-op) when both `min` and `max` are `0`.
|
|
351
367
|
|
|
368
|
+
### RGXLookaroundToken extends RGXClassToken (abstract)
|
|
369
|
+
An abstract base class for lookaround assertion tokens (lookahead and lookbehind). Lookaround assertions match a pattern without consuming characters in the string. Subclasses must implement the `toRgx()`, `negate()`, and `reverse()` methods.
|
|
370
|
+
|
|
371
|
+
#### Static Properties
|
|
372
|
+
- `check(value: unknown): value is RGXLookaroundToken`: A type guard that checks if the given value is an instance of `RGXLookaroundToken`.
|
|
373
|
+
- `assert(value: unknown): asserts value is RGXLookaroundToken`: An assertion that checks if the given value is an instance of `RGXLookaroundToken`. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
|
|
374
|
+
|
|
375
|
+
#### Constructor
|
|
376
|
+
```typescript
|
|
377
|
+
constructor(tokens?: RGXTokenCollectionInput, positive?: boolean)
|
|
378
|
+
```
|
|
379
|
+
- `tokens` (`RGXTokenCollectionInput`, optional): The tokens to include in the lookaround. Internally stored as an `RGXTokenCollection` in 'concat' mode. Defaults to an empty array.
|
|
380
|
+
- `positive` (`boolean`, optional): Whether the lookaround is positive (matches if the pattern is present) or negative (matches if the pattern is absent). Defaults to `true`.
|
|
381
|
+
|
|
382
|
+
#### Properties
|
|
383
|
+
- `tokens` (`RGXTokenCollection`): The internal collection of tokens managed in 'concat' mode.
|
|
384
|
+
- `positive` (`boolean`): Whether the lookaround is positive. Setting this updates `negative` accordingly.
|
|
385
|
+
- `negative` (`boolean`): Whether the lookaround is negative. Setting this updates `positive` accordingly.
|
|
386
|
+
- `isGroup` (`true`): Returns `true` as a constant, indicating this token represents a group.
|
|
387
|
+
- `isRepeatable` (`false`): Returns `false` as a constant, since lookaround assertions cannot be repeated.
|
|
388
|
+
- `rgxGroupWrap` (`false`): Returns `false` as a constant, since the lookaround already wraps itself in a group.
|
|
389
|
+
|
|
390
|
+
#### Abstract Methods
|
|
391
|
+
- `negate() => RGXLookaroundToken`: Returns a new lookaround token of the same type with the opposite positivity, preserving the original tokens.
|
|
392
|
+
- `reverse() => RGXLookaroundToken`: Returns a new lookaround token of the opposite direction (lookahead becomes lookbehind and vice versa), preserving the original tokens and positivity.
|
|
393
|
+
|
|
394
|
+
### RGXLookaheadToken extends RGXLookaroundToken
|
|
395
|
+
A class representing a lookahead assertion. Positive lookaheads (`(?=...)`) match if the pattern is present ahead, while negative lookaheads (`(?!...)`) match if the pattern is absent. This is typically created via the `asLookahead()` method on `RGXClassToken`, but can also be instantiated directly.
|
|
396
|
+
|
|
397
|
+
A function `rgxLookahead` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
398
|
+
|
|
399
|
+
#### Static Properties
|
|
400
|
+
- `check(value: unknown): value is RGXLookaheadToken`: A type guard that checks if the given value is an instance of `RGXLookaheadToken`.
|
|
401
|
+
- `assert(value: unknown): asserts value is RGXLookaheadToken`: An assertion that checks if the given value is an instance of `RGXLookaheadToken`. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
|
|
402
|
+
|
|
403
|
+
#### Methods
|
|
404
|
+
- `negate() => RGXLookaheadToken`: Returns a new `RGXLookaheadToken` with the opposite positivity, preserving the original tokens.
|
|
405
|
+
- `reverse() => RGXLookbehindToken`: Returns a new `RGXLookbehindToken` with the same tokens and positivity.
|
|
406
|
+
- `toRgx() => RegExp`: Resolves the lookahead to a `RegExp`. Positive lookaheads produce `(?=...)` and negative lookaheads produce `(?!...)`.
|
|
407
|
+
|
|
408
|
+
### RGXLookbehindToken extends RGXLookaroundToken
|
|
409
|
+
A class representing a lookbehind assertion. Positive lookbehinds (`(?<=...)`) match if the pattern is present behind, while negative lookbehinds (`(?<!...)`) match if the pattern is absent. This is typically created via the `asLookbehind()` method on `RGXClassToken`, but can also be instantiated directly.
|
|
410
|
+
|
|
411
|
+
A function `rgxLookbehind` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
412
|
+
|
|
413
|
+
#### Static Properties
|
|
414
|
+
- `check(value: unknown): value is RGXLookbehindToken`: A type guard that checks if the given value is an instance of `RGXLookbehindToken`.
|
|
415
|
+
- `assert(value: unknown): asserts value is RGXLookbehindToken`: An assertion that checks if the given value is an instance of `RGXLookbehindToken`. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
|
|
416
|
+
|
|
417
|
+
#### Methods
|
|
418
|
+
- `negate() => RGXLookbehindToken`: Returns a new `RGXLookbehindToken` with the opposite positivity, preserving the original tokens.
|
|
419
|
+
- `reverse() => RGXLookaheadToken`: Returns a new `RGXLookaheadToken` with the same tokens and positivity.
|
|
420
|
+
- `toRgx() => RegExp`: Resolves the lookbehind to a `RegExp`. Positive lookbehinds produce `(?<=...)` and negative lookbehinds produce `(?<!...)`.
|
|
421
|
+
|
|
422
|
+
### RGXClassWrapperToken extends RGXClassToken
|
|
423
|
+
A class that wraps any `RGXToken` as an `RGXClassToken`, giving you access to the extended API class tokens provide. It delegates `isGroup` and `isRepeatable` to the wrapped token where possible.
|
|
424
|
+
|
|
425
|
+
A function `rgxClassWrapper` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
426
|
+
|
|
427
|
+
#### Static Properties
|
|
428
|
+
- `check(value: unknown): value is RGXClassWrapperToken`: A type guard that checks if the given value is an instance of `RGXClassWrapperToken`.
|
|
429
|
+
- `assert(value: unknown): asserts value is RGXClassWrapperToken`: An assertion that checks if the given value is an instance of `RGXClassWrapperToken`. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
|
|
430
|
+
|
|
431
|
+
#### Constructor
|
|
432
|
+
```typescript
|
|
433
|
+
constructor(token: RGXToken)
|
|
434
|
+
```
|
|
435
|
+
- `token` (`RGXToken`): The token to wrap.
|
|
436
|
+
|
|
437
|
+
#### Properties
|
|
438
|
+
- `token` (`RGXToken`): The wrapped token.
|
|
439
|
+
- `isGroup` (`boolean`): Delegates to the wrapped token's group status via `isRGXGroupedToken`. Returns `true` if the wrapped token is a grouped token, otherwise `false`.
|
|
440
|
+
- `isRepeatable` (`boolean`): If the wrapped token is an `RGXClassToken`, delegates to its `isRepeatable` property. Otherwise, returns `true`.
|
|
441
|
+
|
|
442
|
+
#### Methods
|
|
443
|
+
- `unwrap() => RGXToken`: Returns the original wrapped token.
|
|
444
|
+
- `toRgx() => RGXToken`: Returns the original wrapped token (alias for `unwrap()`).
|
|
445
|
+
|
|
352
446
|
### ExtRegExp extends RegExp
|
|
353
447
|
A subclass of `RegExp` that supports custom flag transformers in addition to the standard vanilla regex flags (g, i, m, s, u, y). When constructed, custom flags are extracted, their corresponding transformers are applied to the pattern and vanilla flags, and the resulting transformed `RegExp` is created. The `flags` getter returns both the vanilla flags and any custom flags.
|
|
354
448
|
|
|
@@ -746,24 +840,27 @@ Escapes special regex characters in the given string and brands the result as a
|
|
|
746
840
|
|
|
747
841
|
### resolveRGXToken
|
|
748
842
|
```typescript
|
|
749
|
-
function resolveRGXToken(token: RGXToken, groupWrap?: boolean, topLevel?: boolean): ValidRegexString
|
|
843
|
+
function resolveRGXToken(token: RGXToken, groupWrap?: boolean, topLevel?: boolean, currentFlags?: string): ValidRegexString
|
|
750
844
|
```
|
|
751
845
|
|
|
752
846
|
Resolves an RGX token to a string. No-op tokens resolve to an empty string, literal tokens are included as-is (wrapped in a non-capturing group when `groupWrap` is `true`), native tokens are converted to strings and escaped, convertible tokens are converted using their `toRgx` method and then resolved recursively, and arrays of tokens are resolved as unions of their resolved elements (repeats removed, placed in a non-capturing group when `groupWrap` is `true`).
|
|
753
847
|
|
|
848
|
+
For literal tokens (`RegExp` instances), if the token's flags differ from `currentFlags` in any of the localizable flags (`i`, `m`, `s`), the token is wrapped in an inline modifier group (e.g., `(?i:...)`, `(?-i:...)`, `(?ms-i:...)`) instead of a plain non-capturing group. Non-localizable flags (such as `g`, `u`, `y`, `d`, `v`) are ignored when computing the diff. When an inline modifier group is used, it always wraps the token regardless of the `groupWrap` setting, since the modifier group itself serves as a group.
|
|
849
|
+
|
|
754
850
|
For convertible tokens, if the token has an `rgxGroupWrap` property, that value always takes precedence. If `rgxGroupWrap` is not present, the behavior depends on whether the call is top-level: at the top level, the `groupWrap` parameter is passed through; in recursive calls, it falls back to `true` regardless of the `groupWrap` parameter. This ensures that the caller's `groupWrap` preference only affects the outermost convertible token and does not leak into deeply nested resolution.
|
|
755
851
|
|
|
756
852
|
#### Parameters
|
|
757
853
|
- `token` (`RGXToken`): The RGX token to resolve.
|
|
758
|
-
- `groupWrap` (`boolean`, optional): Whether to wrap literal tokens and array unions in non-capturing groups (`(?:...)`). Defaults to `true`. When `false`, literals use their raw source and array unions omit the wrapping group. For convertible tokens, the token's `rgxGroupWrap` property always takes precedence; otherwise, this value is only passed through at the top level (in recursive calls it falls back to `true`). Array union elements always use `groupWrap=true` internally.
|
|
854
|
+
- `groupWrap` (`boolean`, optional): Whether to wrap literal tokens and array unions in non-capturing groups (`(?:...)`). Defaults to `true`. When `false`, literals use their raw source and array unions omit the wrapping group. For convertible tokens, the token's `rgxGroupWrap` property always takes precedence; otherwise, this value is only passed through at the top level (in recursive calls it falls back to `true`). Array union elements always use `groupWrap=true` internally. Note that when a literal token requires an inline modifier group due to a localizable flag diff, it is always wrapped regardless of this setting.
|
|
759
855
|
- `topLevel` (`boolean`, optional): Tracks whether the current call is the initial (top-level) invocation. Defaults to `true`. **Warning**: This parameter is intended for internal use by the resolver's own recursion. External callers should not set this parameter, as doing so may produce unexpected wrapping behavior.
|
|
856
|
+
- `currentFlags` (`string`, optional): The flags of the current regex context, used to compute inline modifier groups for literal tokens. Defaults to `''`. When a literal token's localizable flags (`i`, `m`, `s`) differ from this value, the resolver wraps the token in an inline modifier group that adds or removes the differing flags locally.
|
|
760
857
|
|
|
761
858
|
#### Returns
|
|
762
859
|
- `ValidRegexString`: The resolved string representation of the RGX token. This is guaranteed to be a valid regex string, as convertible tokens are validated to only produce valid regex strings or arrays of valid regex strings.
|
|
763
860
|
|
|
764
861
|
### rgxConcat
|
|
765
862
|
```typescript
|
|
766
|
-
function rgxConcat(tokens: RGXToken[], groupWrap?: boolean): ValidRegexString
|
|
863
|
+
function rgxConcat(tokens: RGXToken[], groupWrap?: boolean, currentFlags?: string): ValidRegexString
|
|
767
864
|
```
|
|
768
865
|
|
|
769
866
|
A helper function that resolves an array of RGX tokens and concatenates their resolved string representations together. This is useful for cases where you want to concatenate multiple tokens without creating a union between them.
|
|
@@ -771,6 +868,7 @@ A helper function that resolves an array of RGX tokens and concatenates their re
|
|
|
771
868
|
#### Parameters
|
|
772
869
|
- `tokens` (`RGXToken[]`): The array of RGX tokens to resolve and concatenate.
|
|
773
870
|
- `groupWrap` (`boolean`, optional): Whether to wrap individual resolved tokens in non-capturing groups. Passed through to `resolveRGXToken`. Defaults to `true`.
|
|
871
|
+
- `currentFlags` (`string`, optional): The flags of the current regex context, passed through to `resolveRGXToken` as its `currentFlags` parameter. Used to compute inline modifier groups for literal tokens whose localizable flags differ. Defaults to `''`.
|
|
774
872
|
|
|
775
873
|
#### Returns
|
|
776
874
|
- `ValidRegexString`: The concatenated string representation of the resolved RGX tokens. This is guaranteed to be a valid regex string, as it is composed of the resolved forms of RGX tokens, which are all valid regex strings.
|
|
@@ -782,6 +880,8 @@ function rgx(flags?: string): (strings: TemplateStringsArray, ...tokens: RGXToke
|
|
|
782
880
|
|
|
783
881
|
Creates and returns a template tag function that constructs an `ExtRegExp` object from the provided template literal with the provided flags. The template literal can contain RGX tokens, which will be resolved and concatenated with the literal parts to form the final regex pattern.
|
|
784
882
|
|
|
883
|
+
The provided `flags` are passed as `currentFlags` to the resolver, enabling inline modifier groups for any `RegExp` literal tokens whose localizable flags (`i`, `m`, `s`) differ from the parent flags. For example, embedding `/foo/i` in a no-flag context produces `(?i:foo)`, while embedding `/bar/` in an `i`-flag context produces `(?-i:bar)`.
|
|
884
|
+
|
|
785
885
|
Example usages:
|
|
786
886
|
```typescript
|
|
787
887
|
const beginning = /^/;
|
|
@@ -793,6 +893,9 @@ const optionalDigit = /\d?/;
|
|
|
793
893
|
const pattern2 = rgx()`${beginning}optional digit: ${optionalDigit}${end}`; // /^optional digit: \d?$/ - matches the string "optional digit: " followed by an optional digit, anchored to the start and end of the string
|
|
794
894
|
|
|
795
895
|
const pattern3 = rgx()`${beginning}value: ${[word, optionalDigit]}${end}`; // /^value: (?:\w+|\d?)$/ - matches the string "value: " followed by either a word or an optional digit, anchored to the start and end of the string
|
|
896
|
+
|
|
897
|
+
const caseInsensitiveWord = /hello/i;
|
|
898
|
+
const pattern4 = rgx()`${beginning}${caseInsensitiveWord} world${end}`; // /^(?i:hello) world$/ - "hello" matches case-insensitively via an inline modifier group, while " world" remains case-sensitive
|
|
796
899
|
```
|
|
797
900
|
|
|
798
901
|
#### Parameters
|
|
@@ -810,7 +913,7 @@ const pattern3 = rgx()`${beginning}value: ${[word, optionalDigit]}${end}`; // /^
|
|
|
810
913
|
```typescript
|
|
811
914
|
function rgxa(tokens: RGXToken[], flags?: string): ExtRegExp
|
|
812
915
|
```
|
|
813
|
-
As an alternative to using the `rgx` template tag, you can directly call `rgxa` with an array of RGX tokens and optional flags to get an `ExtRegExp` object. This is useful in cases where you don't want to use a template literal.
|
|
916
|
+
As an alternative to using the `rgx` template tag, you can directly call `rgxa` with an array of RGX tokens and optional flags to get an `ExtRegExp` object. This is useful in cases where you don't want to use a template literal. Like `rgx`, the provided `flags` are passed as `currentFlags` to the resolver, enabling inline modifier groups for `RegExp` literal tokens whose localizable flags differ.
|
|
814
917
|
|
|
815
918
|
#### Parameters
|
|
816
919
|
- `tokens` (`RGXToken[]`): The RGX tokens to be resolved and concatenated to form the regex pattern.
|
|
@@ -850,7 +953,23 @@ Removes duplicate tokens from the provided list using `Set` equality and returns
|
|
|
850
953
|
function rgxClassInit(): void
|
|
851
954
|
```
|
|
852
955
|
|
|
853
|
-
Initializes internal method patches required for `RGXClassToken` subclass methods (such as `or`, `group`, and `
|
|
956
|
+
Initializes internal method patches required for `RGXClassToken` subclass methods (such as `or`, `group`, `repeat`, `asLookahead`, and `asLookbehind`) to work correctly. This function is called automatically when importing from the main module entry point, so you typically do not need to call it yourself. It only needs to be called manually if you import directly from sub-modules.
|
|
957
|
+
|
|
958
|
+
### toRGXClassToken
|
|
959
|
+
```typescript
|
|
960
|
+
function toRGXClassToken(token: RGXToken): RGXClassToken
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
Converts any `RGXToken` into an appropriate `RGXClassToken` subclass, giving you access to the extended API that class tokens provide. Tokens that are already class tokens are returned as-is. Array tokens and `RGXTokenCollection` instances in union mode are converted to `RGXClassUnionToken`. `RGXTokenCollection` instances in concat mode are converted to a non-capturing `RGXGroupToken`. All other tokens are wrapped in an `RGXClassWrapperToken`.
|
|
964
|
+
|
|
965
|
+
#### Parameters
|
|
966
|
+
- `token` (`RGXToken`): The token to convert.
|
|
967
|
+
|
|
968
|
+
#### Returns
|
|
969
|
+
- `RGXClassToken`: The corresponding class token:
|
|
970
|
+
- `RGXClassUnionToken` for array tokens and union-mode `RGXTokenCollection` instances.
|
|
971
|
+
- `RGXGroupToken` (non-capturing) for concat-mode `RGXTokenCollection` instances.
|
|
972
|
+
- `RGXClassWrapperToken` for all other tokens.
|
|
854
973
|
|
|
855
974
|
### isInRange
|
|
856
975
|
```typescript
|
package/dist/class/base.d.ts
CHANGED
|
@@ -3,15 +3,20 @@ import { RGXTokenCollectionInput } from "../collection";
|
|
|
3
3
|
import type { RGXClassUnionToken } from "./union";
|
|
4
4
|
import type { RGXGroupToken, RGXGroupTokenArgs } from "./group";
|
|
5
5
|
import type { RGXRepeatToken } from "./repeat";
|
|
6
|
+
import type { RGXLookaheadToken } from "./lookahead";
|
|
7
|
+
import type { RGXLookbehindToken } from "./lookbehind";
|
|
6
8
|
export declare abstract class RGXClassToken {
|
|
7
9
|
abstract toRgx(): RGXToken;
|
|
8
10
|
static check: (value: unknown) => value is RGXClassToken;
|
|
9
11
|
static assert: (value: unknown) => asserts value is RGXClassToken;
|
|
10
12
|
get isGroup(): boolean;
|
|
13
|
+
get isRepeatable(): boolean;
|
|
11
14
|
get rgxGroupWrap(): boolean;
|
|
12
15
|
or(...others: RGXTokenCollectionInput[]): RGXClassUnionToken;
|
|
13
16
|
group(args?: RGXGroupTokenArgs): RGXGroupToken;
|
|
14
17
|
repeat(min?: number, max?: number | null): RGXRepeatToken;
|
|
15
18
|
optional(): RGXRepeatToken;
|
|
19
|
+
asLookahead(positive?: boolean): RGXLookaheadToken;
|
|
20
|
+
asLookbehind(positive?: boolean): RGXLookbehindToken;
|
|
16
21
|
resolve(): ValidRegexString;
|
|
17
22
|
}
|
package/dist/class/base.js
CHANGED
|
@@ -7,6 +7,9 @@ class RGXClassToken {
|
|
|
7
7
|
get isGroup() {
|
|
8
8
|
return false;
|
|
9
9
|
}
|
|
10
|
+
get isRepeatable() {
|
|
11
|
+
return true;
|
|
12
|
+
}
|
|
10
13
|
get rgxGroupWrap() {
|
|
11
14
|
return true;
|
|
12
15
|
}
|
|
@@ -22,6 +25,12 @@ class RGXClassToken {
|
|
|
22
25
|
optional() {
|
|
23
26
|
return this.repeat(0, 1);
|
|
24
27
|
}
|
|
28
|
+
asLookahead(positive = true) {
|
|
29
|
+
throw new errors_1.RGXNotImplementedError('RGXClassToken.asLookahead(positive)', 'call rgxClassInit() first.');
|
|
30
|
+
}
|
|
31
|
+
asLookbehind(positive = true) {
|
|
32
|
+
throw new errors_1.RGXNotImplementedError('RGXClassToken.asLookbehind(positive)', 'call rgxClassInit() first.');
|
|
33
|
+
}
|
|
25
34
|
resolve() {
|
|
26
35
|
return (0, resolve_1.resolveRGXToken)(this);
|
|
27
36
|
}
|
package/dist/class/index.d.ts
CHANGED
package/dist/class/index.js
CHANGED
|
@@ -19,3 +19,8 @@ __exportStar(require("./base"), exports);
|
|
|
19
19
|
__exportStar(require("./union"), exports);
|
|
20
20
|
__exportStar(require("./group"), exports);
|
|
21
21
|
__exportStar(require("./repeat"), exports);
|
|
22
|
+
__exportStar(require("./lookaround"), exports);
|
|
23
|
+
__exportStar(require("./lookahead"), exports);
|
|
24
|
+
__exportStar(require("./lookbehind"), exports);
|
|
25
|
+
__exportStar(require("./wrapper"), exports);
|
|
26
|
+
__exportStar(require("./toRGXClassToken"), exports);
|
package/dist/class/init.js
CHANGED
|
@@ -5,6 +5,10 @@ const base_1 = require("./base");
|
|
|
5
5
|
const union_1 = require("./union");
|
|
6
6
|
const group_1 = require("./group");
|
|
7
7
|
const repeat_1 = require("./repeat");
|
|
8
|
+
const lookaround_1 = require("./lookaround");
|
|
9
|
+
const errors_1 = require("../errors");
|
|
10
|
+
const lookahead_1 = require("./lookahead");
|
|
11
|
+
const lookbehind_1 = require("./lookbehind");
|
|
8
12
|
function rgxClassInit() {
|
|
9
13
|
// Patch RGXClassToken here, Since classes like RGXClassUnionToken are instances of RGXClassToken
|
|
10
14
|
// themselves. If we tried to import RGXClassUnionToken in base.ts, it would cause a circular dependency.
|
|
@@ -25,6 +29,18 @@ function rgxClassInit() {
|
|
|
25
29
|
return new group_1.RGXGroupToken(args, [this]);
|
|
26
30
|
};
|
|
27
31
|
base_1.RGXClassToken.prototype.repeat = function (min = 1, max = min) {
|
|
32
|
+
if (lookaround_1.RGXLookaroundToken.check(this))
|
|
33
|
+
throw new errors_1.RGXNotSupportedError("RGXLookaroundToken.repeat()", "Lookaround tokens cannot be repeated or made optional.");
|
|
28
34
|
return new repeat_1.RGXRepeatToken(this, min, max);
|
|
29
35
|
};
|
|
36
|
+
base_1.RGXClassToken.prototype.asLookahead = function (positive = true) {
|
|
37
|
+
if (lookahead_1.RGXLookaheadToken.check(this))
|
|
38
|
+
return this;
|
|
39
|
+
return new lookahead_1.RGXLookaheadToken([this], positive);
|
|
40
|
+
};
|
|
41
|
+
base_1.RGXClassToken.prototype.asLookbehind = function (positive = true) {
|
|
42
|
+
if (lookbehind_1.RGXLookbehindToken.check(this))
|
|
43
|
+
return this;
|
|
44
|
+
return new lookbehind_1.RGXLookbehindToken([this], positive);
|
|
45
|
+
};
|
|
30
46
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { RGXToken } from "../types";
|
|
2
|
+
import { RGXLookaroundToken } from "./lookaround";
|
|
3
|
+
import { RGXLookbehindToken } from "./lookbehind";
|
|
4
|
+
export declare class RGXLookaheadToken extends RGXLookaroundToken {
|
|
5
|
+
static check: (value: unknown) => value is RGXLookaheadToken;
|
|
6
|
+
static assert: (value: unknown) => asserts value is RGXLookaheadToken;
|
|
7
|
+
negate(): RGXLookaheadToken;
|
|
8
|
+
reverse(): RGXLookbehindToken;
|
|
9
|
+
toRgx(): RGXToken;
|
|
10
|
+
}
|
|
11
|
+
export declare const rgxLookahead: (tokens?: import("..").RGXTokenCollectionInput, positive?: boolean | undefined) => RGXLookaheadToken;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rgxLookahead = exports.RGXLookaheadToken = void 0;
|
|
4
|
+
const internal_1 = require("../internal");
|
|
5
|
+
const lookaround_1 = require("./lookaround");
|
|
6
|
+
const lookbehind_1 = require("./lookbehind");
|
|
7
|
+
class RGXLookaheadToken extends lookaround_1.RGXLookaroundToken {
|
|
8
|
+
negate() {
|
|
9
|
+
return new RGXLookaheadToken(this.tokens, !this.positive);
|
|
10
|
+
}
|
|
11
|
+
reverse() {
|
|
12
|
+
return new lookbehind_1.RGXLookbehindToken(this.tokens, this.positive);
|
|
13
|
+
}
|
|
14
|
+
toRgx() {
|
|
15
|
+
let result = this.tokens.toRgx().source;
|
|
16
|
+
if (this.positive)
|
|
17
|
+
result = `(?=${result})`;
|
|
18
|
+
else
|
|
19
|
+
result = `(?!${result})`;
|
|
20
|
+
return new RegExp(result);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.RGXLookaheadToken = RGXLookaheadToken;
|
|
24
|
+
RGXLookaheadToken.check = (0, internal_1.createClassGuardFunction)(RGXLookaheadToken);
|
|
25
|
+
RGXLookaheadToken.assert = (0, internal_1.createAssertClassGuardFunction)(RGXLookaheadToken);
|
|
26
|
+
exports.rgxLookahead = (0, internal_1.createConstructFunction)(RGXLookaheadToken);
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { RGXTokenCollection, RGXTokenCollectionInput } from "../collection";
|
|
2
|
+
import { RGXClassToken } from "./base";
|
|
3
|
+
export declare abstract class RGXLookaroundToken extends RGXClassToken {
|
|
4
|
+
tokens: RGXTokenCollection;
|
|
5
|
+
_negative: boolean;
|
|
6
|
+
static check: (value: unknown) => value is RGXLookaroundToken;
|
|
7
|
+
static assert: (value: unknown) => asserts value is RGXLookaroundToken;
|
|
8
|
+
get isGroup(): true;
|
|
9
|
+
get isRepeatable(): false;
|
|
10
|
+
get rgxGroupWrap(): false;
|
|
11
|
+
set negative(value: boolean);
|
|
12
|
+
get negative(): boolean;
|
|
13
|
+
set positive(value: boolean);
|
|
14
|
+
get positive(): boolean;
|
|
15
|
+
constructor(tokens?: RGXTokenCollectionInput, positive?: boolean);
|
|
16
|
+
abstract negate(): RGXLookaroundToken;
|
|
17
|
+
abstract reverse(): RGXLookaroundToken;
|
|
18
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RGXLookaroundToken = void 0;
|
|
4
|
+
const collection_1 = require("../collection");
|
|
5
|
+
const base_1 = require("./base");
|
|
6
|
+
const errors_1 = require("../errors");
|
|
7
|
+
class RGXLookaroundToken extends base_1.RGXClassToken {
|
|
8
|
+
get isGroup() {
|
|
9
|
+
return true;
|
|
10
|
+
}
|
|
11
|
+
get isRepeatable() {
|
|
12
|
+
return false;
|
|
13
|
+
}
|
|
14
|
+
get rgxGroupWrap() {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
set negative(value) {
|
|
18
|
+
this._negative = value;
|
|
19
|
+
}
|
|
20
|
+
get negative() {
|
|
21
|
+
return this._negative;
|
|
22
|
+
}
|
|
23
|
+
set positive(value) {
|
|
24
|
+
this.negative = !value;
|
|
25
|
+
}
|
|
26
|
+
get positive() {
|
|
27
|
+
return !this.negative;
|
|
28
|
+
}
|
|
29
|
+
constructor(tokens = [], positive = true) {
|
|
30
|
+
super();
|
|
31
|
+
this._negative = false;
|
|
32
|
+
this.positive = positive;
|
|
33
|
+
if (tokens instanceof collection_1.RGXTokenCollection && tokens.mode === 'union')
|
|
34
|
+
this.tokens = new collection_1.RGXTokenCollection(tokens, 'concat');
|
|
35
|
+
else
|
|
36
|
+
this.tokens = new collection_1.RGXTokenCollection(tokens, 'concat');
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.RGXLookaroundToken = RGXLookaroundToken;
|
|
40
|
+
// The createClassGuard function only accepts non-abstract classes, so we
|
|
41
|
+
// manually define the guard and assertion functions for RGXLookaroundToken here.
|
|
42
|
+
RGXLookaroundToken.check = (value) => value instanceof RGXLookaroundToken;
|
|
43
|
+
RGXLookaroundToken.assert = (value) => {
|
|
44
|
+
if (!(value instanceof RGXLookaroundToken)) {
|
|
45
|
+
throw new errors_1.RGXInvalidTokenError("Invalid token type", { type: "custom", values: ["instance of RGXLookaroundToken"] }, value);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RGXTokenCollectionInput } from "../collection";
|
|
2
|
+
import { RGXToken } from "../types";
|
|
3
|
+
import { RGXLookaheadToken } from "./lookahead";
|
|
4
|
+
import { RGXLookaroundToken } from "./lookaround";
|
|
5
|
+
export declare class RGXLookbehindToken extends RGXLookaroundToken {
|
|
6
|
+
static check: (value: unknown) => value is RGXLookbehindToken;
|
|
7
|
+
static assert: (value: unknown) => asserts value is RGXLookbehindToken;
|
|
8
|
+
negate(): RGXLookbehindToken;
|
|
9
|
+
reverse(): RGXLookaheadToken;
|
|
10
|
+
toRgx(): RGXToken;
|
|
11
|
+
}
|
|
12
|
+
export declare const rgxLookbehind: (tokens?: RGXTokenCollectionInput, positive?: boolean | undefined) => RGXLookbehindToken;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rgxLookbehind = exports.RGXLookbehindToken = void 0;
|
|
4
|
+
const internal_1 = require("../internal");
|
|
5
|
+
const lookahead_1 = require("./lookahead");
|
|
6
|
+
const lookaround_1 = require("./lookaround");
|
|
7
|
+
class RGXLookbehindToken extends lookaround_1.RGXLookaroundToken {
|
|
8
|
+
negate() {
|
|
9
|
+
return new RGXLookbehindToken(this.tokens, !this.positive);
|
|
10
|
+
}
|
|
11
|
+
reverse() {
|
|
12
|
+
return new lookahead_1.RGXLookaheadToken(this.tokens, this.positive);
|
|
13
|
+
}
|
|
14
|
+
toRgx() {
|
|
15
|
+
let result = this.tokens.toRgx().source;
|
|
16
|
+
if (this.positive)
|
|
17
|
+
result = `(?<=${result})`;
|
|
18
|
+
else
|
|
19
|
+
result = `(?<!${result})`;
|
|
20
|
+
return new RegExp(result);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.RGXLookbehindToken = RGXLookbehindToken;
|
|
24
|
+
RGXLookbehindToken.check = (0, internal_1.createClassGuardFunction)(RGXLookbehindToken);
|
|
25
|
+
RGXLookbehindToken.assert = (0, internal_1.createAssertClassGuardFunction)(RGXLookbehindToken);
|
|
26
|
+
exports.rgxLookbehind = (0, internal_1.createConstructFunction)(RGXLookbehindToken);
|
package/dist/class/repeat.js
CHANGED
|
@@ -30,6 +30,9 @@ class RGXRepeatToken extends base_1.RGXClassToken {
|
|
|
30
30
|
return this._token;
|
|
31
31
|
}
|
|
32
32
|
set token(value) {
|
|
33
|
+
if ((0, typeGuards_1.isRGXToken)(value, "class") && !value.isRepeatable) {
|
|
34
|
+
throw new errors_1.RGXNotSupportedError(`Repeating ${value.constructor.name} tokens`, "The token was manually marked as non-repeatable.");
|
|
35
|
+
}
|
|
33
36
|
// Make sure we are always working with a grouped token.
|
|
34
37
|
if ((0, typeGuards_1.isRGXGroupedToken)(value))
|
|
35
38
|
this._token = value;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.toRGXClassToken = toRGXClassToken;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
const typeGuards_1 = require("../typeGuards");
|
|
6
|
+
const union_1 = require("./union");
|
|
7
|
+
const collection_1 = require("../collection");
|
|
8
|
+
const group_1 = require("./group");
|
|
9
|
+
const wrapper_1 = require("./wrapper");
|
|
10
|
+
function toRGXClassToken(token) {
|
|
11
|
+
if (base_1.RGXClassToken.check(token))
|
|
12
|
+
return token;
|
|
13
|
+
if ((0, typeGuards_1.isRGXArrayToken)(token))
|
|
14
|
+
return new union_1.RGXClassUnionToken(token);
|
|
15
|
+
if (collection_1.RGXTokenCollection.check(token) && token.mode === 'union')
|
|
16
|
+
return new union_1.RGXClassUnionToken(token.tokens);
|
|
17
|
+
if (collection_1.RGXTokenCollection.check(token) && token.mode === 'concat')
|
|
18
|
+
return new group_1.RGXGroupToken({ capturing: false }, token);
|
|
19
|
+
return new wrapper_1.RGXClassWrapperToken(token);
|
|
20
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { RGXToken } from "../types";
|
|
2
|
+
import { RGXClassToken } from "./base";
|
|
3
|
+
export declare class RGXClassWrapperToken extends RGXClassToken {
|
|
4
|
+
token: RGXToken;
|
|
5
|
+
static check: (value: unknown) => value is RGXClassWrapperToken;
|
|
6
|
+
static assert: (value: unknown) => asserts value is RGXClassWrapperToken;
|
|
7
|
+
constructor(token: RGXToken);
|
|
8
|
+
get isGroup(): boolean;
|
|
9
|
+
get isRepeatable(): boolean;
|
|
10
|
+
unwrap(): RGXToken;
|
|
11
|
+
toRgx(): RGXToken;
|
|
12
|
+
}
|
|
13
|
+
export declare const rgxClassWrapper: (token: RGXToken) => RGXClassWrapperToken;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rgxClassWrapper = exports.RGXClassWrapperToken = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
const typeGuards_1 = require("../typeGuards");
|
|
6
|
+
const internal_1 = require("../internal");
|
|
7
|
+
class RGXClassWrapperToken extends base_1.RGXClassToken {
|
|
8
|
+
constructor(token) {
|
|
9
|
+
super();
|
|
10
|
+
this.token = token;
|
|
11
|
+
}
|
|
12
|
+
get isGroup() {
|
|
13
|
+
return (0, typeGuards_1.isRGXGroupedToken)(this.token);
|
|
14
|
+
}
|
|
15
|
+
get isRepeatable() {
|
|
16
|
+
if ((0, typeGuards_1.isRGXToken)(this.token, 'class'))
|
|
17
|
+
return this.token.isRepeatable;
|
|
18
|
+
// Assume any other token is repeatable, since we don't know its implementation.
|
|
19
|
+
return true;
|
|
20
|
+
}
|
|
21
|
+
unwrap() {
|
|
22
|
+
return this.token;
|
|
23
|
+
}
|
|
24
|
+
toRgx() {
|
|
25
|
+
return this.unwrap();
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
exports.RGXClassWrapperToken = RGXClassWrapperToken;
|
|
29
|
+
RGXClassWrapperToken.check = (0, internal_1.createClassGuardFunction)(RGXClassWrapperToken);
|
|
30
|
+
RGXClassWrapperToken.assert = (0, internal_1.createAssertClassGuardFunction)(RGXClassWrapperToken);
|
|
31
|
+
exports.rgxClassWrapper = (0, internal_1.createConstructFunction)(RGXClassWrapperToken);
|
package/dist/concat.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import * as t from "./types";
|
|
2
|
-
export declare function rgxConcat(tokens: t.RGXToken[], groupWrap?: boolean): t.ValidRegexString;
|
|
2
|
+
export declare function rgxConcat(tokens: t.RGXToken[], groupWrap?: boolean, currentFlags?: string): t.ValidRegexString;
|
package/dist/concat.js
CHANGED
|
@@ -3,6 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.rgxConcat = rgxConcat;
|
|
4
4
|
const resolve_1 = require("./resolve");
|
|
5
5
|
// Wrapper for letting an array of tokens be resolved as a concatenation instead of a union.
|
|
6
|
-
function rgxConcat(tokens, groupWrap = true) {
|
|
7
|
-
return tokens.map(t => (0, resolve_1.resolveRGXToken)(t, groupWrap)).join('');
|
|
6
|
+
function rgxConcat(tokens, groupWrap = true, currentFlags = '') {
|
|
7
|
+
return tokens.map(t => (0, resolve_1.resolveRGXToken)(t, groupWrap, true, currentFlags)).join('');
|
|
8
8
|
}
|
package/dist/errors/base.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type RGXErrorCode = 'UNKNOWN' | 'INVALID_RGX_TOKEN' | 'INVALID_REGEX_STRING' | 'INVALID_REGEX_FLAGS' | 'INVALID_VANILLA_REGEX_FLAGS' | 'NOT_IMPLEMENTED' | 'INVALID_IDENTIFIER' | 'OUT_OF_BOUNDS' | 'INVALID_FLAG_TRANSFORMER_KEY' | 'FLAG_TRANSFORMER_CONFLICT';
|
|
1
|
+
export type RGXErrorCode = 'UNKNOWN' | 'INVALID_RGX_TOKEN' | 'INVALID_REGEX_STRING' | 'INVALID_REGEX_FLAGS' | 'INVALID_VANILLA_REGEX_FLAGS' | 'NOT_IMPLEMENTED' | 'NOT_SUPPORTED' | 'INVALID_IDENTIFIER' | 'OUT_OF_BOUNDS' | 'INVALID_FLAG_TRANSFORMER_KEY' | 'FLAG_TRANSFORMER_CONFLICT';
|
|
2
2
|
export declare class RGXError extends Error {
|
|
3
3
|
_message: string;
|
|
4
4
|
code: RGXErrorCode;
|
package/dist/errors/index.d.ts
CHANGED
package/dist/errors/index.js
CHANGED
|
@@ -24,3 +24,4 @@ __exportStar(require("./invalidIdentifier"), exports);
|
|
|
24
24
|
__exportStar(require("./outOfBounds"), exports);
|
|
25
25
|
__exportStar(require("./invalidFlagTransformerKey"), exports);
|
|
26
26
|
__exportStar(require("./flagTransformerConflict"), exports);
|
|
27
|
+
__exportStar(require("./notSupported"), exports);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RGXNotSupportedError = void 0;
|
|
4
|
+
const base_1 = require("./base");
|
|
5
|
+
class RGXNotSupportedError extends base_1.RGXError {
|
|
6
|
+
constructor(functionality, message = null) {
|
|
7
|
+
super(message || "", "NOT_SUPPORTED");
|
|
8
|
+
this.functionality = functionality;
|
|
9
|
+
this.name = "RGXNotSupportedError";
|
|
10
|
+
}
|
|
11
|
+
calcMessage(message) {
|
|
12
|
+
const result = `${this.functionality} is not supported.`;
|
|
13
|
+
if (message)
|
|
14
|
+
return result + ` Additional info: ${message}`;
|
|
15
|
+
else
|
|
16
|
+
return result;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
exports.RGXNotSupportedError = RGXNotSupportedError;
|
package/dist/index.js
CHANGED
|
@@ -37,7 +37,7 @@ __exportStar(require("./flag-transformer"), exports);
|
|
|
37
37
|
(0, flag_transformer_1.registerCustomFlagTransformers)();
|
|
38
38
|
function rgxa(tokens, flags = '') {
|
|
39
39
|
(0, ExtRegExp_1.assertValidRegexFlags)(flags);
|
|
40
|
-
const pattern = (0, concat_1.rgxConcat)(tokens);
|
|
40
|
+
const pattern = (0, concat_1.rgxConcat)(tokens, true, flags);
|
|
41
41
|
return (0, ExtRegExp_1.extRegExp)(pattern, flags);
|
|
42
42
|
}
|
|
43
43
|
function rgx(flags = '') {
|
package/dist/resolve.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import * as t from "./types";
|
|
2
2
|
export declare function escapeRegex(value: string): t.ValidRegexString;
|
|
3
|
-
export declare function resolveRGXToken(token: t.RGXToken, groupWrap?: boolean, topLevel?: boolean): t.ValidRegexString;
|
|
3
|
+
export declare function resolveRGXToken(token: t.RGXToken, groupWrap?: boolean, topLevel?: boolean, currentFlags?: string): t.ValidRegexString;
|
package/dist/resolve.js
CHANGED
|
@@ -41,21 +41,42 @@ const tg = __importStar(require("./typeGuards"));
|
|
|
41
41
|
function escapeRegex(value) {
|
|
42
42
|
return value.replaceAll(/[\-\^\$.*+?^${}()|[\]\\]/g, '\\$&');
|
|
43
43
|
}
|
|
44
|
-
function
|
|
44
|
+
function localizableVanillaRegexFlagDiff(prev, next) {
|
|
45
|
+
// Remove anything other than the "ims" flags from both strings, as
|
|
46
|
+
// other flags are not localizable (including our custom flags).
|
|
47
|
+
prev = prev.replaceAll(/[^ims]/g, '');
|
|
48
|
+
next = next.replaceAll(/[^ims]/g, '');
|
|
49
|
+
// Format <added flags>-<removed flags>
|
|
50
|
+
const added = [...new Set(next.split(''))].filter(flag => !prev.includes(flag)).join('');
|
|
51
|
+
const removed = [...new Set(prev.split(''))].filter(flag => !next.includes(flag)).join('');
|
|
52
|
+
if (added === '' && removed === '')
|
|
53
|
+
return '';
|
|
54
|
+
if (removed === '')
|
|
55
|
+
return `${added}`;
|
|
56
|
+
return `${added}-${removed}`;
|
|
57
|
+
}
|
|
58
|
+
function resolveRGXToken(token, groupWrap = true, topLevel = true, currentFlags = '') {
|
|
45
59
|
if (tg.isRGXNoOpToken(token))
|
|
46
60
|
return '';
|
|
47
61
|
if (tg.isRGXLiteralToken(token)) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
62
|
+
const localizableFlagDiff = localizableVanillaRegexFlagDiff(currentFlags, token.flags);
|
|
63
|
+
currentFlags = token.flags;
|
|
64
|
+
if (!localizableFlagDiff) {
|
|
65
|
+
if (groupWrap)
|
|
66
|
+
return '(?:' + token.source + ')';
|
|
67
|
+
else
|
|
68
|
+
return token.source;
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return `(?${localizableFlagDiff}:${token.source})`;
|
|
72
|
+
}
|
|
52
73
|
}
|
|
53
74
|
if (tg.isRGXNativeToken(token))
|
|
54
75
|
return escapeRegex(String(token));
|
|
55
76
|
if (tg.isRGXConvertibleToken(token)) {
|
|
56
77
|
// The top-level group-wrapping preference propogates to a direct convertible token, but after that
|
|
57
78
|
// the preference falls back to true whenever a token doesn't explicitly specify a preference.
|
|
58
|
-
return resolveRGXToken(token.toRgx(), token.rgxGroupWrap ?? (topLevel ? groupWrap : true), false);
|
|
79
|
+
return resolveRGXToken(token.toRgx(), token.rgxGroupWrap ?? (topLevel ? groupWrap : true), false, currentFlags);
|
|
59
80
|
}
|
|
60
81
|
// Interpret arrays as unions
|
|
61
82
|
if (tg.isRGXArrayToken(token, false)) {
|
|
@@ -66,11 +87,11 @@ function resolveRGXToken(token, groupWrap = true, topLevel = true) {
|
|
|
66
87
|
token = [...(0, class_1.removeRgxUnionDuplicates)(...token)];
|
|
67
88
|
// Don't preserve group wrapping preference for the recursive calls
|
|
68
89
|
if (groupWrap)
|
|
69
|
-
return '(?:' + token.map(t => resolveRGXToken(t, true, false)).join('|') + ')';
|
|
90
|
+
return '(?:' + token.map(t => resolveRGXToken(t, true, false, currentFlags)).join('|') + ')';
|
|
70
91
|
else
|
|
71
|
-
return token.map(t => resolveRGXToken(t, true, false)).join('|');
|
|
92
|
+
return token.map(t => resolveRGXToken(t, true, false, currentFlags)).join('|');
|
|
72
93
|
}
|
|
73
|
-
return resolveRGXToken(token[0]);
|
|
94
|
+
return resolveRGXToken(token[0], true, false, currentFlags);
|
|
74
95
|
}
|
|
75
96
|
// Ignoring this line since it should be impossible to reach if the types are correct, but we need it to satisfy the return type
|
|
76
97
|
/* istanbul ignore next */
|
package/dist/typeGuards.js
CHANGED
|
@@ -223,7 +223,7 @@ function assertValidRegexString(value) {
|
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
function isValidVanillaRegexFlags(value) {
|
|
226
|
-
const patternMatch = /^[
|
|
226
|
+
const patternMatch = /^[gimsuydv]*$/.test(value);
|
|
227
227
|
if (!patternMatch)
|
|
228
228
|
return false;
|
|
229
229
|
// No repeated flags allowed
|