@ptolemy2002/rgx 4.6.1 → 4.8.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.
Files changed (43) hide show
  1. package/README.md +113 -25
  2. package/dist/class/base.d.ts +5 -0
  3. package/dist/class/base.js +9 -0
  4. package/dist/class/group.d.ts +2 -2
  5. package/dist/class/index.d.ts +3 -0
  6. package/dist/class/index.js +3 -0
  7. package/dist/class/init.js +16 -0
  8. package/dist/class/lookahead.d.ts +11 -0
  9. package/dist/class/lookahead.js +26 -0
  10. package/dist/class/lookaround.d.ts +18 -0
  11. package/dist/class/lookaround.js +47 -0
  12. package/dist/class/lookbehind.d.ts +12 -0
  13. package/dist/class/lookbehind.js +26 -0
  14. package/dist/class/repeat.d.ts +3 -3
  15. package/dist/class/repeat.js +5 -6
  16. package/dist/errors/base.d.ts +6 -1
  17. package/dist/errors/base.js +14 -1
  18. package/dist/errors/flagTransformerConflict.d.ts +1 -1
  19. package/dist/errors/flagTransformerConflict.js +2 -2
  20. package/dist/errors/index.d.ts +1 -0
  21. package/dist/errors/index.js +1 -0
  22. package/dist/errors/invalidFlagTransformerKey.d.ts +1 -1
  23. package/dist/errors/invalidFlagTransformerKey.js +2 -2
  24. package/dist/errors/invalidIdentifier.d.ts +1 -1
  25. package/dist/errors/invalidIdentifier.js +2 -2
  26. package/dist/errors/invalidRegexFlags.d.ts +1 -1
  27. package/dist/errors/invalidRegexFlags.js +2 -2
  28. package/dist/errors/invalidRegexString.d.ts +1 -1
  29. package/dist/errors/invalidRegexString.js +2 -2
  30. package/dist/errors/invalidToken.d.ts +1 -1
  31. package/dist/errors/invalidToken.js +3 -3
  32. package/dist/errors/invalidVanillaRegexFlags.d.ts +1 -1
  33. package/dist/errors/invalidVanillaRegexFlags.js +2 -2
  34. package/dist/errors/notImplemented.d.ts +1 -1
  35. package/dist/errors/notImplemented.js +4 -4
  36. package/dist/errors/notSupported.d.ts +6 -0
  37. package/dist/errors/notSupported.js +19 -0
  38. package/dist/errors/outOfBounds.d.ts +1 -1
  39. package/dist/errors/outOfBounds.js +4 -4
  40. package/dist/typeGuards.d.ts +2 -0
  41. package/dist/typeGuards.js +15 -0
  42. package/dist/types.d.ts +7 -0
  43. package/package.json +1 -1
package/README.md CHANGED
@@ -10,7 +10,10 @@ type RGXLiteralToken = RegExp;
10
10
  type RGXNativeToken = string | number | boolean | RGXNoOpToken;
11
11
  type RGXConvertibleToken = { toRgx: () => RGXToken, readonly rgxGroupWrap?: boolean };
12
12
  type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
13
+
13
14
  type RGXClassTokenConstructor = new (...args: unknown[]) => RGXClassToken;
15
+ type RGXGroupedToken = RGXToken[] | RGXLiteralToken | (RGXClassToken & { isGroup: true }) | RGXGroupedConvertibleToken;
16
+ type RGXGroupedConvertibleToken = { toRgx: () => RGXGroupedToken, readonly rgxGroupWrap: true };
14
17
 
15
18
  const validRegexSymbol = Symbol('rgx.ValidRegex');
16
19
  type ValidRegexBrandSymbol = typeof validRegexSymbol;
@@ -41,7 +44,7 @@ type RGXTokenFromType<T extends RGXTokenTypeGuardInput> =
41
44
  // ... see source for full definition
42
45
  ;
43
46
 
44
- 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';
45
48
 
46
49
  type RangeObject = {
47
50
  min?: number | null;
@@ -83,6 +86,9 @@ constructor(message: string, code?: RGXErrorCode)
83
86
  #### Properties
84
87
  - `code` (`RGXErrorCode`): The error code associated with the error, which can be used to identify the type of error that occurred.
85
88
 
89
+ #### Methods
90
+ - `toString() => string`: Returns a formatted string in the format `${name}: ${message}`. Subclasses customize the message portion via internal formatting rather than overriding `toString()` directly, so all `RGXError` subclasses produce consistently formatted strings through this single method.
91
+
86
92
  ### RGXInvalidTokenError extends RGXError
87
93
  A specific error class for invalid RGX tokens. This error is thrown when a value fails validation as a specific RGX token type. The error code is set to `INVALID_RGX_TOKEN` on instantiation.
88
94
 
@@ -137,8 +143,18 @@ constructor(functionality: string, message?: string | null)
137
143
  #### Properties
138
144
  - `functionality` (`string`): The description of the unimplemented functionality.
139
145
 
140
- #### Methods
141
- - `toString() => string`: Returns a formatted string indicating the unimplemented functionality and any additional message.
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.
142
158
 
143
159
  ### RGXInvalidIdentifierError extends RGXError
144
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.
@@ -153,9 +169,6 @@ constructor(message: string, got: string)
153
169
  #### Properties
154
170
  - `got` (`string`): The actual string that was received, which failed validation.
155
171
 
156
- #### Methods
157
- - `toString() => string`: Returns a formatted string indicating the invalid identifier and the reason for failure.
158
-
159
172
  ### RGXInvalidRegexFlagsError extends RGXError
160
173
  A specific error class for invalid regex flags (including both vanilla and custom registered flags). This error is thrown when a string fails validation as valid regex flags. The error code is set to `INVALID_REGEX_FLAGS` on instantiation.
161
174
 
@@ -169,9 +182,6 @@ constructor(message: string, got: string)
169
182
  #### Properties
170
183
  - `got` (`string`): The actual string that was received, which failed validation.
171
184
 
172
- #### Methods
173
- - `toString() => string`: Returns a formatted string indicating the invalid flags and the reason for failure.
174
-
175
185
  ### RGXInvalidFlagTransformerKeyError extends RGXError
176
186
  A specific error class for invalid flag transformer keys. This error is thrown when an invalid key is provided to `registerFlagTransformer` (e.g., a key that is not a single character). The error code is set to `INVALID_FLAG_TRANSFORMER_KEY` on instantiation.
177
187
 
@@ -185,9 +195,6 @@ constructor(message: string, got: string)
185
195
  #### Properties
186
196
  - `got` (`string`): The actual key string that was received, which failed validation.
187
197
 
188
- #### Methods
189
- - `toString() => string`: Returns a formatted string indicating the invalid key and the reason for failure.
190
-
191
198
  ### RGXFlagTransformerConflictError extends RGXError
192
199
  A specific error class for flag transformer conflicts. This error is thrown when attempting to register a flag transformer with a key that conflicts with an existing vanilla regex flag or an already-registered transformer. The error code is set to `FLAG_TRANSFORMER_CONFLICT` on instantiation.
193
200
 
@@ -201,9 +208,6 @@ constructor(message: string, got: string)
201
208
  #### Properties
202
209
  - `got` (`string`): The conflicting key string.
203
210
 
204
- #### Methods
205
- - `toString() => string`: Returns a formatted string indicating the conflict and the reason for failure.
206
-
207
211
  ### RGXOutOfBoundsError extends RGXError
208
212
  A specific error class for out-of-bounds values. This error is thrown when a numeric value falls outside an expected range. The error code is set to `OUT_OF_BOUNDS` on instantiation.
209
213
 
@@ -229,7 +233,6 @@ constructor(message: string, got: number, { min, max, inclusiveLeft, inclusiveRi
229
233
  - `failedAtMin() => boolean`: Returns `true` if the `got` value is below the minimum bound (respecting `inclusiveLeft`), otherwise `false`. Returns `false` if `min` is `null`.
230
234
  - `failedAtMax() => boolean`: Returns `true` if the `got` value is above the maximum bound (respecting `inclusiveRight`), otherwise `false`. Returns `false` if `max` is `null`.
231
235
  - `failedAtAny() => boolean`: Returns `true` if the value failed at either the minimum or maximum bound.
232
- - `toString() => string`: Returns a formatted string indicating the out-of-bounds value, the expected range, and which bound was violated.
233
236
 
234
237
  ### RGXTokenCollection
235
238
  A class representing a collection of RGX tokens. This class manages collections of RGX tokens like an array, but with additional metadata about the collection mode (union or concat). Since `toRgx()` returns a `RegExp`, instances of this class satisfy the `RGXConvertibleToken` interface and can be used directly as tokens in `rgx`, `rgxa`, and other token-accepting functions.
@@ -272,14 +275,17 @@ An abstract base class for creating custom RGX token classes. Subclasses must im
272
275
 
273
276
  #### Properties
274
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`.
275
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).
276
280
 
277
281
  #### Methods
278
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.
279
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.
280
- - `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.
281
- - `optional() => RGXRepeatToken`: Shorthand for `repeat(0, 1)`. Wraps this token in an `RGXRepeatToken` that matches the token zero or one times.
282
- - `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`, and `RGXRepeatToken`.
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`.
283
289
 
284
290
  ### RGXClassUnionToken extends RGXClassToken
285
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.
@@ -326,8 +332,8 @@ constructor(args?: RGXGroupTokenArgs, tokens?: RGXTokenCollectionInput)
326
332
  - `tokens` (`RGXTokenCollection`): The internal collection of tokens managed in 'concat' mode.
327
333
  - `name` (`string | null`): The name of the group. Setting this to a non-null value validates it as a valid identifier via `assertValidIdentifier`.
328
334
  - `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`.
329
- - `isGroup` (`boolean`): Returns `true`, indicating this token represents a group.
330
- - `rgxGroupWrap` (`boolean`): Returns `false`, since the group already wraps itself, preventing the resolver from double-wrapping.
335
+ - `isGroup` (`true`): Returns `true` as a constant, indicating this token represents a group.
336
+ - `rgxGroupWrap` (`false`): Returns `false` as a constant, since the group already wraps itself, preventing the resolver from double-wrapping.
331
337
 
332
338
  #### Methods
333
339
  - `toRgx() => RegExp`: Resolves the group by concatenating the internal tokens and wrapping the result in the appropriate group syntax: `(?<name>...)` for named groups, `(?:...)` for non-capturing groups, or `(...)` for capturing groups.
@@ -345,20 +351,74 @@ A function `rgxRepeat` is provided with the same parameters as this class' const
345
351
  ```typescript
346
352
  constructor(token: RGXToken, min?: number, max?: number | null)
347
353
  ```
348
- - `token` (`RGXToken`): The token to repeat. If the token is not already a group (i.e., not an array, `RegExp`, or an `RGXClassToken` with `isGroup` set to `true`), it will be automatically wrapped in an `RGXGroupToken` that is non-capturing.
354
+ - `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`.
349
355
  - `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`.
350
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`.
351
357
 
352
358
  #### Properties
353
- - `token` (`RGXToken`): The token being repeated. Setting this will automatically wrap non-group tokens in an `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`.
354
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.
355
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.
356
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).
357
- - `rgxGroupWrap` (`boolean`): Returns `false`, since the quantifier suffix binds tightly to the preceding group and does not need additional wrapping.
363
+ - `rgxGroupWrap` (`false`): Returns `false` as a constant, since the quantifier suffix binds tightly to the preceding group and does not need additional wrapping.
358
364
 
359
365
  #### Methods
360
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`.
361
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
+
362
422
  ### ExtRegExp extends RegExp
363
423
  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.
364
424
 
@@ -639,6 +699,34 @@ Asserts that the given value is a valid RGX token, optionally narrowed to a spec
639
699
  #### Returns
640
700
  - `void`: This function does not return a value, but will throw an error if the assertion fails.
641
701
 
702
+ ### isRGXGroupedToken
703
+ ```typescript
704
+ function isRGXGroupedToken(value: unknown, contentCheck?: boolean): value is RGXGroupedToken
705
+ ```
706
+
707
+ 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. Class tokens are only groups if they have the `isGroup` property set to `true`. Convertible tokens are groups if they have `rgxGroupWrap` set to `true` and their `toRgx()` method returns a grouped token.
708
+
709
+ #### Parameters
710
+ - `value` (`unknown`): The value to check.
711
+ - `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.
712
+
713
+ #### Returns
714
+ - `boolean`: `true` if the value is a grouped token, otherwise `false`.
715
+
716
+ ### assertRGXGroupedToken
717
+ ```typescript
718
+ function assertRGXGroupedToken(value: unknown, contentCheck?: boolean): asserts value is RGXGroupedToken
719
+ ```
720
+
721
+ Asserts that the given value is a grouped token. Uses the same logic as `isRGXGroupedToken`. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
722
+
723
+ #### Parameters
724
+ - `value` (`unknown`): The value to assert.
725
+ - `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.
726
+
727
+ #### Returns
728
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
729
+
642
730
  ### isValidRegexString
643
731
  ```typescript
644
732
  function isValidRegexString(value: string): value is ValidRegexString
@@ -832,7 +920,7 @@ Removes duplicate tokens from the provided list using `Set` equality and returns
832
920
  function rgxClassInit(): void
833
921
  ```
834
922
 
835
- Initializes internal method patches required for `RGXClassToken` subclass methods (such as `or`, `group`, and `repeat`) 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.
923
+ 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.
836
924
 
837
925
  ### isInRange
838
926
  ```typescript
@@ -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
  }
@@ -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
  }
@@ -14,8 +14,8 @@ export declare class RGXGroupToken extends RGXClassToken {
14
14
  set name(value: string | null);
15
15
  get capturing(): boolean;
16
16
  set capturing(value: boolean);
17
- get isGroup(): boolean;
18
- get rgxGroupWrap(): boolean;
17
+ get isGroup(): true;
18
+ get rgxGroupWrap(): false;
19
19
  constructor({ name, capturing }?: RGXGroupTokenArgs, tokens?: RGXTokenCollectionInput);
20
20
  toRgx(): RegExp;
21
21
  }
@@ -3,3 +3,6 @@ export * from "./base";
3
3
  export * from "./union";
4
4
  export * from "./group";
5
5
  export * from "./repeat";
6
+ export * from "./lookaround";
7
+ export * from "./lookahead";
8
+ export * from "./lookbehind";
@@ -19,3 +19,6 @@ __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);
@@ -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);
@@ -1,7 +1,7 @@
1
- import { RGXToken } from "../types";
1
+ import { RGXGroupedToken, RGXToken } from "../types";
2
2
  import { RGXClassToken } from "./base";
3
3
  export declare class RGXRepeatToken extends RGXClassToken {
4
- _token: RGXToken;
4
+ _token: RGXGroupedToken;
5
5
  _min: number;
6
6
  _max: number | null;
7
7
  static check: (value: unknown) => value is RGXRepeatToken;
@@ -12,7 +12,7 @@ export declare class RGXRepeatToken extends RGXClassToken {
12
12
  set max(value: number | null);
13
13
  get token(): RGXToken;
14
14
  set token(value: RGXToken);
15
- get rgxGroupWrap(): boolean;
15
+ get rgxGroupWrap(): false;
16
16
  constructor(token: RGXToken, min?: number, max?: number | null);
17
17
  get repeaterSuffix(): string;
18
18
  toRgx(): RGXToken;
@@ -30,12 +30,11 @@ class RGXRepeatToken extends base_1.RGXClassToken {
30
30
  return this._token;
31
31
  }
32
32
  set token(value) {
33
- // Arrays and Literals are implicitly grouped.
34
- const isGroup = (0, typeGuards_1.isRGXToken)(value, "array") ||
35
- (0, typeGuards_1.isRGXToken)(value, "literal") ||
36
- ((0, typeGuards_1.isRGXToken)(value, "class") && value.isGroup);
37
- // Make sure we are always working with a group token.
38
- if (isGroup)
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
+ }
36
+ // Make sure we are always working with a grouped token.
37
+ if ((0, typeGuards_1.isRGXGroupedToken)(value))
39
38
  this._token = value;
40
39
  else
41
40
  this._token = new group_1.RGXGroupToken({ capturing: false }, value);
@@ -1,5 +1,10 @@
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
+ _message: string;
3
4
  code: RGXErrorCode;
5
+ get message(): string;
6
+ set message(value: string);
4
7
  constructor(message: string, code?: RGXErrorCode);
8
+ calcMessage(message: string): string;
9
+ toString(): string;
5
10
  }
@@ -2,13 +2,26 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.RGXError = void 0;
4
4
  class RGXError extends Error {
5
+ get message() {
6
+ return this.calcMessage(this._message);
7
+ }
8
+ set message(value) {
9
+ this._message = value;
10
+ }
5
11
  constructor(message, code) {
6
- super(message);
12
+ super();
7
13
  this.code = 'UNKNOWN';
8
14
  this.name = 'RGXError';
15
+ this.message = message;
9
16
  if (code) {
10
17
  this.code = code;
11
18
  }
12
19
  }
20
+ calcMessage(message) {
21
+ return message;
22
+ }
23
+ toString() {
24
+ return `${this.name}: ${this.message}`;
25
+ }
13
26
  }
14
27
  exports.RGXError = RGXError;
@@ -2,5 +2,5 @@ import { RGXError } from "./";
2
2
  export declare class RGXFlagTransformerConflictError extends RGXError {
3
3
  got: string;
4
4
  constructor(message: string, got: string);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,8 +8,8 @@ class RGXFlagTransformerConflictError extends errors_1.RGXError {
8
8
  this.name = 'RGXFlagTransformerConflictError';
9
9
  this.got = got;
10
10
  }
11
- toString() {
12
- return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
11
+ calcMessage(message) {
12
+ return `${message}; Got: ${JSON.stringify(this.got)}`;
13
13
  }
14
14
  }
15
15
  exports.RGXFlagTransformerConflictError = RGXFlagTransformerConflictError;
@@ -8,3 +8,4 @@ export * from './invalidIdentifier';
8
8
  export * from './outOfBounds';
9
9
  export * from './invalidFlagTransformerKey';
10
10
  export * from './flagTransformerConflict';
11
+ export * from './notSupported';
@@ -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);
@@ -2,5 +2,5 @@ import { RGXError } from "./";
2
2
  export declare class RGXInvalidFlagTransformerKeyError extends RGXError {
3
3
  got: string;
4
4
  constructor(message: string, got: string);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,8 +8,8 @@ class RGXInvalidFlagTransformerKeyError extends errors_1.RGXError {
8
8
  this.name = 'RGXInvalidFlagTransformerKeyError';
9
9
  this.got = got;
10
10
  }
11
- toString() {
12
- return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
11
+ calcMessage(message) {
12
+ return `${message}; Got: ${JSON.stringify(this.got)}`;
13
13
  }
14
14
  }
15
15
  exports.RGXInvalidFlagTransformerKeyError = RGXInvalidFlagTransformerKeyError;
@@ -2,5 +2,5 @@ import { RGXError } from "./";
2
2
  export declare class RGXInvalidIdentifierError extends RGXError {
3
3
  got: string;
4
4
  constructor(message: string, got: string);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,8 +8,8 @@ class RGXInvalidIdentifierError extends errors_1.RGXError {
8
8
  this.name = 'RGXInvalidIdentifierError';
9
9
  this.got = got;
10
10
  }
11
- toString() {
12
- return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
11
+ calcMessage(message) {
12
+ return `${message}; Got: ${JSON.stringify(this.got)}`;
13
13
  }
14
14
  }
15
15
  exports.RGXInvalidIdentifierError = RGXInvalidIdentifierError;
@@ -2,5 +2,5 @@ import { RGXError } from "./";
2
2
  export declare class RGXInvalidRegexFlagsError extends RGXError {
3
3
  got: string;
4
4
  constructor(message: string, got: string);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,8 +8,8 @@ class RGXInvalidRegexFlagsError extends errors_1.RGXError {
8
8
  this.name = 'RGXInvalidRegexFlagsError';
9
9
  this.got = got;
10
10
  }
11
- toString() {
12
- return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
11
+ calcMessage(message) {
12
+ return `${message}; Got: ${JSON.stringify(this.got)}`;
13
13
  }
14
14
  }
15
15
  exports.RGXInvalidRegexFlagsError = RGXInvalidRegexFlagsError;
@@ -2,5 +2,5 @@ import { RGXError } from "./";
2
2
  export declare class RGXInvalidRegexStringError extends RGXError {
3
3
  got: string;
4
4
  constructor(message: string, got: string);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,8 +8,8 @@ class RGXInvalidRegexStringError extends errors_1.RGXError {
8
8
  this.name = 'RGXInvalidRegexStringError';
9
9
  this.got = got;
10
10
  }
11
- toString() {
12
- return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
11
+ calcMessage(message) {
12
+ return `${message}; Got: ${JSON.stringify(this.got)}`;
13
13
  }
14
14
  }
15
15
  exports.RGXInvalidRegexStringError = RGXInvalidRegexStringError;
@@ -12,5 +12,5 @@ export declare class RGXInvalidTokenError extends RGXError {
12
12
  got: unknown;
13
13
  setExpected(expected: ExpectedTokenType | null): string;
14
14
  constructor(message: string, expected: ExpectedTokenType | null, got: unknown);
15
- toString(): string;
15
+ calcMessage(message: string): string;
16
16
  }
@@ -6,7 +6,7 @@ const js_utils_1 = require("@ptolemy2002/js-utils");
6
6
  const class_1 = require("../class");
7
7
  const tokenExpectationMap = {
8
8
  'no-op': ['null', 'undefined'],
9
- 'literal': ['RegExp'],
9
+ 'literal': ['RegExp', 'ExtRegExp'],
10
10
  'native': ['string', 'number', 'boolean', 'null', 'undefined'],
11
11
  'convertible': ['object with a toRgx method that returns a valid native/literal token or an array of valid native/literal tokens'],
12
12
  'array': ['array of native/literal/convertible tokens'],
@@ -45,9 +45,9 @@ class RGXInvalidTokenError extends errors_1.RGXError {
45
45
  this.got = got;
46
46
  this.setExpected(expected);
47
47
  }
48
- toString() {
48
+ calcMessage(message) {
49
49
  const gotString = class_1.RGXClassToken.check(this.got) ? `instance of ${this.got.constructor.name}` : JSON.stringify(this.got);
50
- return `${this.name}: ${this.message}; Expected: ${this.expected}; Got: [${gotString}]`;
50
+ return `${message}; Expected: ${this.expected}; Got: [${gotString}]`;
51
51
  }
52
52
  }
53
53
  exports.RGXInvalidTokenError = RGXInvalidTokenError;
@@ -2,5 +2,5 @@ import { RGXError } from "./";
2
2
  export declare class RGXInvalidVanillaRegexFlagsError extends RGXError {
3
3
  got: string;
4
4
  constructor(message: string, got: string);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,8 +8,8 @@ class RGXInvalidVanillaRegexFlagsError extends errors_1.RGXError {
8
8
  this.name = 'RGXInvalidVanillaRegexFlagsError';
9
9
  this.got = got;
10
10
  }
11
- toString() {
12
- return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
11
+ calcMessage(message) {
12
+ return `${message}; Got: ${JSON.stringify(this.got)}`;
13
13
  }
14
14
  }
15
15
  exports.RGXInvalidVanillaRegexFlagsError = RGXInvalidVanillaRegexFlagsError;
@@ -2,5 +2,5 @@ import { RGXError } from "./base";
2
2
  export declare class RGXNotImplementedError extends RGXError {
3
3
  functionality: string;
4
4
  constructor(functionality: string, message?: string | null);
5
- toString(): string;
5
+ calcMessage(message: string): string;
6
6
  }
@@ -8,10 +8,10 @@ class RGXNotImplementedError extends base_1.RGXError {
8
8
  this.functionality = functionality;
9
9
  this.name = "RGXNotImplementedError";
10
10
  }
11
- toString() {
12
- const result = `${this.name}: ${this.functionality} is not implemented yet.`;
13
- if (this.message)
14
- return result + ` Additional info: ${this.message}`;
11
+ calcMessage(message) {
12
+ const result = `${this.functionality} is not implemented yet.`;
13
+ if (message)
14
+ return result + ` Additional info: ${message}`;
15
15
  else
16
16
  return result;
17
17
  }
@@ -0,0 +1,6 @@
1
+ import { RGXError } from "./base";
2
+ export declare class RGXNotSupportedError extends RGXError {
3
+ functionality: string;
4
+ constructor(functionality: string, message?: string | null);
5
+ calcMessage(message: string): string;
6
+ }
@@ -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;
@@ -14,7 +14,7 @@ export declare class RGXOutOfBoundsError extends RGXError {
14
14
  failedAtMin(): boolean;
15
15
  failedAtMax(): boolean;
16
16
  failedAtAny(): boolean;
17
- toString(): string;
17
+ calcMessage(message: string): string;
18
18
  }
19
19
  export declare function isInRange(value: number, { min, max, inclusiveLeft, inclusiveRight }?: RangeObject): boolean;
20
20
  export declare function assertInRange(value: number, range?: RangeObject, message?: string): void;
@@ -41,7 +41,7 @@ class RGXOutOfBoundsError extends base_1.RGXError {
41
41
  failedAtAny() {
42
42
  return this.failedAtMin() || this.failedAtMax();
43
43
  }
44
- toString() {
44
+ calcMessage(message) {
45
45
  const rangeParts = [];
46
46
  if (this.min !== null) {
47
47
  if (this.inclusiveLeft)
@@ -58,7 +58,7 @@ class RGXOutOfBoundsError extends base_1.RGXError {
58
58
  const rangeStr = rangeParts.join(" and ");
59
59
  // Determine which one was failed
60
60
  if (!this.failedAtAny()) {
61
- return `${this.name}: ${this.message}; Got: [${this.got}]; Expected: [${rangeStr}]`;
61
+ return `${message}; Got: [${this.got}]; Expected: [${rangeStr}]`;
62
62
  }
63
63
  else if (this.failedAtMin()) {
64
64
  let thirdPart;
@@ -66,7 +66,7 @@ class RGXOutOfBoundsError extends base_1.RGXError {
66
66
  thirdPart = `${this.got} == ${this.min}`;
67
67
  else
68
68
  thirdPart = `${this.got} < ${this.min}`;
69
- return `${this.name}: ${this.message}; Got: [${this.got}]; Expected: [${rangeStr}]; ${thirdPart}`;
69
+ return `${message}; Got: [${this.got}]; Expected: [${rangeStr}]; ${thirdPart}`;
70
70
  }
71
71
  else {
72
72
  let thirdPart;
@@ -74,7 +74,7 @@ class RGXOutOfBoundsError extends base_1.RGXError {
74
74
  thirdPart = `${this.got} == ${this.max}`;
75
75
  else
76
76
  thirdPart = `${this.got} > ${this.max}`;
77
- return `${this.name}: ${this.message}; Got: [${this.got}]; Expected: [${rangeStr}]; ${thirdPart}`;
77
+ return `${message}; Got: [${this.got}]; Expected: [${rangeStr}]; ${thirdPart}`;
78
78
  }
79
79
  }
80
80
  }
@@ -16,6 +16,8 @@ export declare function rgxTokenTypeToFlat(type: t.RGXTokenType): t.RGXTokenType
16
16
  export declare function rgxTokenTypeGuardInputToFlat(type: t.RGXTokenTypeGuardInput): t.RGXTokenTypeFlat | null;
17
17
  export declare function isRGXToken<T extends t.RGXTokenTypeGuardInput = null>(value: unknown, type?: T, matchLength?: boolean): value is t.RGXTokenFromType<T>;
18
18
  export declare function assertRGXToken<T extends t.RGXTokenTypeGuardInput = null>(value: unknown, type?: T, matchLength?: boolean): asserts value is t.RGXTokenFromType<T>;
19
+ export declare function isRGXGroupedToken(value: unknown, contentCheck?: boolean): value is t.RGXGroupedToken;
20
+ export declare function assertRGXGroupedToken(value: unknown, contentCheck?: boolean): asserts value is t.RGXGroupedToken;
19
21
  export declare function isValidRegexString(value: string): value is t.ValidRegexString;
20
22
  export declare function assertValidRegexString(value: string): asserts value is t.ValidRegexString;
21
23
  export declare function isValidVanillaRegexFlags(value: string): value is t.ValidVanillaRegexFlags;
@@ -53,6 +53,8 @@ exports.rgxTokenTypeToFlat = rgxTokenTypeToFlat;
53
53
  exports.rgxTokenTypeGuardInputToFlat = rgxTokenTypeGuardInputToFlat;
54
54
  exports.isRGXToken = isRGXToken;
55
55
  exports.assertRGXToken = assertRGXToken;
56
+ exports.isRGXGroupedToken = isRGXGroupedToken;
57
+ exports.assertRGXGroupedToken = assertRGXGroupedToken;
56
58
  exports.isValidRegexString = isValidRegexString;
57
59
  exports.assertValidRegexString = assertValidRegexString;
58
60
  exports.isValidVanillaRegexFlags = isValidVanillaRegexFlags;
@@ -193,6 +195,19 @@ function assertRGXToken(value, type = null, matchLength = true) {
193
195
  throw new e.RGXInvalidTokenError("Invalid RGX token", flatType === null ? null : { type: "tokenType", values: [flatType] }, value);
194
196
  }
195
197
  }
198
+ function isRGXGroupedToken(value, contentCheck = true) {
199
+ // Arrays and Literals are implicitly groups.
200
+ // Classes are only groups if they have the isGroup property set to true.
201
+ return (isRGXArrayToken(value, contentCheck) ||
202
+ isRGXToken(value, "literal") ||
203
+ (isRGXToken(value, "class") && value.isGroup) ||
204
+ (isRGXConvertibleToken(value, false) && value.rgxGroupWrap === true && (!contentCheck || isRGXGroupedToken(value.toRgx()))));
205
+ }
206
+ function assertRGXGroupedToken(value, contentCheck = true) {
207
+ if (!isRGXGroupedToken(value, contentCheck)) {
208
+ throw new e.RGXInvalidTokenError("Invalid group token, class token is not group, or convertible token is not group wrapped.", { type: "custom", values: ['array', 'literal', 'class', 'convertible'] }, value);
209
+ }
210
+ }
196
211
  function isValidRegexString(value) {
197
212
  try {
198
213
  new RegExp(value);
package/dist/types.d.ts CHANGED
@@ -11,6 +11,13 @@ export type RGXConvertibleToken = {
11
11
  };
12
12
  export type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
13
13
  export type RGXClassTokenConstructor = new (...args: unknown[]) => RGXClassToken;
14
+ export type RGXGroupedToken = RGXToken[] | RGXLiteralToken | (RGXClassToken & {
15
+ isGroup: true;
16
+ }) | RGXGroupedConvertibleToken;
17
+ export type RGXGroupedConvertibleToken = {
18
+ toRgx: () => RGXGroupedToken;
19
+ readonly rgxGroupWrap: true;
20
+ };
14
21
  export type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | 'class' | RGXTokenType[];
15
22
  export type RGXTokenTypeFlat = Exclude<RGXTokenType, RGXTokenType[]> | "array";
16
23
  export type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ptolemy2002/rgx",
3
- "version": "4.6.1",
3
+ "version": "4.8.0",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",