@ptolemy2002/rgx 7.2.0 → 7.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -24,6 +24,7 @@ type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToke
24
24
  type RGXClassTokenConstructor = new (...args: unknown[]) => RGXClassToken;
25
25
  type RGXGroupedToken = RGXToken[] | RGXLiteralToken | RGXGroupedConvertibleToken;
26
26
  type RGXGroupedConvertibleToken = (RGXConvertibleToken & { readonly rgxIsGroup: true }) | (Omit<RGXConvertibleToken, "toRgx"> & { toRgx: () => RGXGroupedToken, readonly rgxGroupWrap: true });
27
+ type RGXRepeatableConvertibleToken = RGXConvertibleToken & { readonly rgxIsRepeatable: true | undefined };
27
28
 
28
29
  const validRegexSymbol = Symbol('rgx.ValidRegex');
29
30
  type ValidRegexBrandSymbol = typeof validRegexSymbol;
@@ -45,7 +46,7 @@ type ValidIdentifier = Branded<string, [ValidIdentifierBrandSymbol]>;
45
46
 
46
47
  type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | 'class' | RGXTokenType[];
47
48
  type RGXTokenTypeFlat = Exclude<RGXTokenType, RGXTokenType[]> | "array";
48
- type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof RegExp | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
49
+ type RGXTokenTypeGuardInput = "repeatable" | RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof RegExp | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
49
50
  type RGXTokenFromType<T extends RGXTokenTypeGuardInput> =
50
51
  // Maps token type strings to their corresponding types, e.g.:
51
52
  // 'no-op' -> RGXNoOpToken, 'literal' -> RGXLiteralToken, etc.
@@ -911,7 +912,7 @@ Converts an `RGXTokenType` to its flat equivalent `RGXTokenTypeFlat`. If the typ
911
912
  function rgxTokenTypeGuardInputToFlat(type: RGXTokenTypeGuardInput): RGXTokenTypeFlat | null
912
913
  ```
913
914
 
914
- Converts an `RGXTokenTypeGuardInput` to its flat equivalent. If the type is `null`, it returns `null`; if it is an array, it returns `'array'`; if it is an `RGXClassTokenConstructor` (a constructor for an `RGXClassToken` subclass), it returns `'class'` (making it slightly lossy in that case); otherwise, it returns the type as-is.
915
+ Converts an `RGXTokenTypeGuardInput` to its flat equivalent. If the type is `null`, it returns `null`; if it is an array, it returns `'array'`; if it is a RegEx constructor, it returns `'literal`; if it is the `RGXTokenCollection` constructor, it returns `'convertible'`; if it is an `RGXClassTokenConstructor` (a constructor for an `RGXClassToken` subclass), it returns `'class'` (making it slightly lossy in that case); otherwise, it returns the type as-is.
915
916
 
916
917
  #### Parameters
917
918
  - `type` (`RGXTokenTypeGuardInput`): The type guard input to convert.
@@ -930,6 +931,8 @@ When `type` is a constructor, it performs an `instanceof` check against that spe
930
931
 
931
932
  When `type` is an array, it checks that every element of the value array is a valid RGX token matching the corresponding type in the `type` array. If `matchLength` is `true` (the default), it also requires that the value array has the same length as the type array; if `false`, it allows the value array to be longer than the type array, as long as all elements up to the length of the type array match and all elements after that are still valid RGX tokens of any type.
932
933
 
934
+ When `type` is `"repeatable"`, it passes for any token that is not convertible, then checks if `rgxIsRepeatable` is `true | undefined` for convertible tokens.
935
+
933
936
  #### Parameters
934
937
  - `value` (`unknown`): The value to check.
935
938
  - `type` (`T`, optional): The token type to check against. Can be a token type string, `null` (checks against all token types), an `RGXClassTokenConstructor` (checks via `instanceof`), or an array of these. Defaults to `null`.
@@ -1110,7 +1113,9 @@ function rgx(flags?: string, multiline?: boolean): (strings: TemplateStringsArra
1110
1113
 
1111
1114
  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. Before constructing the pattern, any convertible token that defines `rgxAcceptInsertion` is checked; if it returns `false` or a string, an `RGXInsertionRejectedError` is thrown with details about the reason and exactly where the rejection occurred.
1112
1115
 
1113
- When `multiline` is `true` (the default), the literal string parts of the template are processed to strip newlines, trim leading whitespace from each line, and remove empty lines, then joined together. This allows you to write regex patterns across multiple lines in the source code for readability without the newlines and indentation becoming part of the pattern. Only the literal string parts between tokens are affected — interpolated values (tokens) are preserved as-is, including string tokens passed via `${"..."}`. When `multiline` is `false`, all literal string parts are preserved exactly as written, including newlines and whitespace.
1116
+ When `multiline` is `true` (the default), the literal string parts of the template are processed to strip newlines, trim leading whitespace from each line, and remove empty lines, then joined together. This allows you to write regex patterns across multiple lines in the source code for readability without the newlines and indentation becoming part of the pattern. Only the literal string parts between tokens are affected — interpolated values (tokens) are preserved as-is, including string tokens passed via `${"..."}`. Also, comments (denoted with `//`) ending a line or on a line by themselves are stripped. If a command ends a line, that line is also stripped of whitespace on the right side.
1117
+
1118
+ When `multiline` is `false`, all literal string parts are preserved exactly as written, including newlines and whitespace.
1114
1119
 
1115
1120
  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)`.
1116
1121
 
@@ -1147,7 +1152,7 @@ const pattern6 = rgx()`
1147
1152
  #### Parameters
1148
1153
  **Direct**
1149
1154
  - `flags` (`string`, optional): The regex flags to apply to the resulting `ExtRegExp` object (e.g., 'g', 'i', 'm', or custom registered flags). If not provided, no flags will be applied. If provided and not valid regex flags (vanilla or registered custom), an `RGXInvalidRegexFlagsError` will be thrown.
1150
- - `multiline` (`boolean`, optional): Whether to strip newlines and trim leading whitespace from the literal string parts of the template. Defaults to `true`. When `true`, each literal string part is split by newlines, each line has its leading whitespace trimmed, empty lines are removed, and the remaining lines are joined together. Interpolated tokens (including string tokens via `${"..."}`) are not affected. When `false`, literal string parts are preserved exactly as written.
1155
+ - `multiline` (`boolean`, optional): Whether to strip newlines and trim leading whitespace from the literal string parts of the template. Defaults to `true`. When `true`, each literal string part is split by newlines, each line has its leading whitespace trimmed, empty lines are removed, comments (denoted with `//`) ending a line or on a line by themselves are stripped, and the remaining lines are joined together. Interpolated tokens (including string tokens via `${"..."}`) are not affected. When `false`, literal string parts are preserved exactly as written.
1151
1156
 
1152
1157
  **Template Tag**
1153
1158
  - `strings` (`TemplateStringsArray`): The literal parts of the template string.
@@ -1179,7 +1184,7 @@ A helper function that creates an `RGXWalker` instance from an interpolation of
1179
1184
  #### Parameters
1180
1185
  - `source` (`string`): An arbitrary string value that will be included in the `source` property of the walker object.
1181
1186
  - `options` (`RGXWOptions<R>`, optional): Additional options for configuring the behavior of the resulting `RGXWalker`. This includes:
1182
- - `multiline` (`boolean`, optional): Whether to strip newlines and trim leading whitespace from the literal string parts of the template. Defaults to `true`. When `true`, each literal string part is split by newlines, each line has its leading whitespace trimmed, empty lines are removed, and the remaining lines are joined together. Interpolated tokens (including string tokens via `${"..."}`) are not affected. When `false`, literal string parts are preserved exactly as written.
1187
+ - `multiline` (`boolean`, optional): Whether to strip newlines and trim leading whitespace from the literal string parts of the template. Defaults to `true`. When `true`, each literal string part is split by newlines, each line has its leading whitespace trimmed, empty lines are removed, comments (denoted with `//`) ending a line or on a line by themselves are stripped, and the remaining lines are joined together. Interpolated tokens (including string tokens via `${"..."}`) are not affected. When `false`, literal string parts are preserved exactly as written.
1183
1188
  - `reduced` (`R`, optional): An optional initial value for the walker's `reduced` property, which can be used to accumulate results across matches.
1184
1189
 
1185
1190
  #### Returns
@@ -1640,7 +1645,9 @@ Since these are defined as native tokens (strings), they are automatically wrapp
1640
1645
  | --- | --- | --- |
1641
1646
  | `"any"` | `.` | Matches any single character (except newline by default) |
1642
1647
  | `"start"` | `^` | Start of string anchor |
1648
+ | `"line-start"` | `^` (with `m` flag) | Start of line anchor |
1643
1649
  | `"end"` | `$` | End of string anchor |
1650
+ | `"line-end"` | `$` (with `m` flag) | End of line anchor |
1644
1651
  | `"word-bound"` | `\b` | Word boundary |
1645
1652
  | `"non-word-bound"` | `\B` | Non-word boundary |
1646
1653
  | `"word-bound-start"` | `(?<=\W)(?=\w)` | Start of a word |
@@ -32,7 +32,7 @@ class RGXRepeatToken extends base_1.RGXClassToken {
32
32
  return this._token;
33
33
  }
34
34
  set token(value) {
35
- if ((0, typeGuards_1.isRGXToken)(value, "convertible") && typeof value.rgxIsRepeatable === "boolean" && !value.rgxIsRepeatable) {
35
+ if ((0, typeGuards_1.isRGXToken)(value, "convertible") && !(0, typeGuards_1.isRGXToken)(value, "repeatable")) {
36
36
  if ((0, typeGuards_1.isRGXToken)(value, "class")) {
37
37
  throw new errors_1.RGXNotSupportedError(`Repeating ${value.constructor.name} tokens`, "The token was manually marked as non-repeatable.");
38
38
  }
package/dist/constants.js CHANGED
@@ -61,6 +61,13 @@ defineRGXConstant("start", {
61
61
  return /^/;
62
62
  }
63
63
  });
64
+ defineRGXConstant("line-start", {
65
+ rgxGroupWrap: false,
66
+ rgxIsRepeatable: false,
67
+ toRgx() {
68
+ return /^/m;
69
+ }
70
+ });
64
71
  defineRGXConstant("end", {
65
72
  rgxGroupWrap: false,
66
73
  rgxIsRepeatable: false,
@@ -68,6 +75,13 @@ defineRGXConstant("end", {
68
75
  return /$/;
69
76
  }
70
77
  });
78
+ defineRGXConstant("line-end", {
79
+ rgxGroupWrap: false,
80
+ rgxIsRepeatable: false,
81
+ toRgx() {
82
+ return /$/m;
83
+ }
84
+ });
71
85
  defineRGXConstant("word-bound", {
72
86
  rgxGroupWrap: false,
73
87
  rgxIsRepeatable: false,
@@ -15,8 +15,22 @@ function taggedTemplateToArray(strings, tokens, multiline) {
15
15
  array.push(string);
16
16
  }
17
17
  else {
18
- // Remove all empty lines and trim whitespace from the start of each line.
19
- let lines = string.split("\n").map(line => line.trimStart()).filter(line => line.length > 0).join("");
18
+ // Remove all empty lines, remove comments, and trim whitespace from the start of each line.
19
+ let lines = string
20
+ .split("\n")
21
+ .map(line => line.trimStart())
22
+ // Remove comments both for the start of the line.
23
+ .filter(line => !line.startsWith("//"))
24
+ .filter(line => line.length > 0)
25
+ // Remove comments at the end of the line.
26
+ .map(line => {
27
+ const commentIndex = line.indexOf("//");
28
+ if (commentIndex !== -1) {
29
+ return line.substring(0, commentIndex).trimEnd();
30
+ }
31
+ return line;
32
+ })
33
+ .join("");
20
34
  array.push(lines);
21
35
  }
22
36
  }
@@ -65,6 +65,8 @@ const e = __importStar(require("./errors"));
65
65
  const is_callable_1 = __importDefault(require("is-callable"));
66
66
  const internal_1 = require("./internal");
67
67
  const class_1 = require("./class");
68
+ const ExtRegExp_1 = require("./ExtRegExp");
69
+ const collection_1 = require("./collection");
68
70
  function isRGXNoOpToken(value) {
69
71
  return value === null || value === undefined;
70
72
  }
@@ -171,8 +173,14 @@ function rgxTokenTypeGuardInputToFlat(type) {
171
173
  return null;
172
174
  if (Array.isArray(type))
173
175
  return 'array';
176
+ if (type === RegExp || type === ExtRegExp_1.ExtRegExp)
177
+ return 'literal';
178
+ if (type === collection_1.RGXTokenCollection)
179
+ return 'convertible';
174
180
  if ((0, internal_1.isConstructor)(type))
175
181
  return 'class';
182
+ if (type === "repeatable")
183
+ return null;
176
184
  return type;
177
185
  }
178
186
  function isRGXToken(value, type = null, matchLength = true) {
@@ -192,6 +200,11 @@ function isRGXToken(value, type = null, matchLength = true) {
192
200
  return true;
193
201
  if (typeMatches('convertible') && isRGXConvertibleToken(value))
194
202
  return true;
203
+ // Non-covertible tokens are repeatable by default. Convertible tokens are only non-repeatable if they have the rgxIsRepeatable property set to false.
204
+ if (type === 'repeatable' && !isRGXConvertibleToken(value, false))
205
+ return true;
206
+ if (type === 'repeatable' && isRGXConvertibleToken(value))
207
+ return value.rgxIsRepeatable ?? true;
195
208
  if (typeMatches('array') && isRGXArrayToken(value))
196
209
  return true;
197
210
  if (Array.isArray(type) && Array.isArray(value) && (!matchLength || type.length === value.length)) {
package/dist/types.d.ts CHANGED
@@ -22,10 +22,13 @@ export type RGXGroupedConvertibleToken = (RGXConvertibleToken & {
22
22
  toRgx: () => RGXGroupedToken;
23
23
  readonly rgxGroupWrap: true;
24
24
  });
25
+ export type RGXRepeatableConvertibleToken = RGXConvertibleToken & {
26
+ readonly rgxIsRepeatable: true | undefined;
27
+ };
25
28
  export type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | 'class' | RGXTokenType[];
26
29
  export type RGXTokenTypeFlat = Exclude<RGXTokenType, RGXTokenType[]> | "array";
27
- export type RGXTokenTypeGuardInput = RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof RegExp | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
28
- export type RGXTokenFromType<T extends RGXTokenTypeGuardInput> = T extends null ? RGXToken : T extends 'no-op' ? RGXNoOpToken : T extends 'literal' ? RGXLiteralToken : T extends 'native' ? RGXNativeToken : T extends 'convertible' ? RGXConvertibleToken : T extends 'class' ? RGXClassToken : T extends 'array' ? RGXToken[] : T extends new (...args: unknown[]) => infer R ? R : T extends RGXTokenTypeGuardInput[] ? {
30
+ export type RGXTokenTypeGuardInput = "repeatable" | RGXTokenTypeFlat | null | RGXClassTokenConstructor | typeof RegExp | typeof ExtRegExp | typeof RGXTokenCollection | RGXTokenTypeGuardInput[];
31
+ export type RGXTokenFromType<T extends RGXTokenTypeGuardInput> = T extends null ? RGXToken : T extends 'no-op' ? RGXNoOpToken : T extends 'literal' ? RGXLiteralToken : T extends 'native' ? RGXNativeToken : T extends 'convertible' ? RGXConvertibleToken : T extends 'class' ? RGXClassToken : T extends 'array' ? RGXToken[] : T extends 'repeatable' ? Exclude<RGXToken, RGXConvertibleToken> | RGXRepeatableConvertibleToken : T extends new (...args: unknown[]) => infer R ? R : T extends RGXTokenTypeGuardInput[] ? {
29
32
  [K in keyof T]: T[K] extends RGXTokenTypeGuardInput ? RGXTokenFromType<T[K]> : never;
30
33
  } : never;
31
34
  export type RangeObject = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ptolemy2002/rgx",
3
- "version": "7.2.0",
3
+ "version": "7.4.0",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",