@ptolemy2002/rgx 1.2.0 → 2.0.1

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
@@ -10,17 +10,67 @@ type RGXNoOpToken = null | undefined;
10
10
  type RGXLiteralToken = RegExp;
11
11
  type RGXNativeToken = string | number | boolean | RGXNoOpToken;
12
12
  type RGXConvertibleToken = { toRgx: () => MaybeArray<RGXNativeToken | RGXLiteralToken> };
13
- type RGXToken = RGXNativeToken | RGXConvertibleToken | RGXToken[];
13
+ type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
14
14
 
15
- const validRegexSymbol = Symbol('ValidRegex');
15
+ const validRegexSymbol = Symbol('rgx.ValidRegex');
16
16
  type ValidRegexBrandSymbol = typeof validRegexSymbol;
17
17
  type ValidRegexString = Branded<string, [ValidRegexBrandSymbol]>;
18
18
 
19
- type RGXTokenType = 'no-op' | 'native' | 'convertible' | RGXTokenType[];
19
+ const validVanillaRegexFlagsSymbol = Symbol('rgx.ValidVanillaRegexFlags');
20
+ type ValidVanillaRegexFlagsBrandSymbol = typeof validVanillaRegexFlagsSymbol;
21
+ type ValidVanillaRegexFlags = Branded<string, [ValidVanillaRegexFlagsBrandSymbol]>;
22
+
23
+ type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | RGXTokenType[];
20
24
  type RGXTokenFromType<T extends RGXTokenType> =
21
25
  // ... see source for full definition
22
26
  ;
27
+
28
+ type RGXErrorCode = 'UNKNOWN' | 'INVALID_RGX_TOKEN' | 'INVALID_REGEX_STRING' | 'INVALID_VANILLA_REGEX_FLAGS';
29
+ ```
30
+
31
+ ## Classes
32
+ The library exports the following classes:
33
+
34
+ ### RGXError
35
+ A custom error class for RGX-related errors. This can be used to throw specific errors related to RGX token validation or resolution.
36
+
37
+ #### Constructor
38
+ ```typescript
39
+ constructor(message: string, code?: RGXErrorCode)
40
+ ```
41
+ - `message` (`string`): The error message.
42
+ - `code` (`RGXErrorCode`, optional): An optional error code that can be used to categorize the error. If not provided, it defaults to 'UNKNOWN'.
43
+
44
+ ### RGXInvalidTokenError extends RGXError
45
+ A specific error class for invalid RGX tokens. This error is thrown when a value fails validation as a specific RGX token type.
46
+
47
+ #### Constructor
48
+ ```typescript
49
+ constructor(message: string, expected: string | null, got: unknown)
50
+ ```
51
+ - `message` (`string`): The error message.
52
+ - `expected` (`string` | `null`): A description of the expected token type. If `null`, will use a default message indicating the expected types of any RGX token.
53
+ - `got` (`unknown`): The actual value that was received, which failed validation.
54
+
55
+ ### RGXInvalidRegexStringError extends RGXError
56
+ A specific error class for invalid regex strings. This error is thrown when a string fails validation as a valid regex string.
57
+
58
+ #### Constructor
59
+ ```typescript
60
+ constructor(message: string, got: string)
61
+ ```
62
+ - `message` (`string`): The error message.
63
+ - `got` (`string`): The actual string that was received, which failed validation.
64
+
65
+ ### RGXInvalidVanillaRegexFlagsError extends RGXError
66
+ A specific error class for invalid vanilla regex flags. This error is thrown when a string fails validation as valid vanilla regex flags.
67
+
68
+ #### Constructor
69
+ ```typescript
70
+ constructor(message: string, got: string)
23
71
  ```
72
+ - `message` (`string`): The error message.
73
+ - `got` (`string`): The actual string that was received, which failed validation.
24
74
 
25
75
  ## Functions
26
76
  The following functions are exported by the library:
@@ -38,6 +88,19 @@ Checks if the given value is a no-op token (`null` or `undefined`).
38
88
  #### Returns
39
89
  - `boolean`: `true` if the value is a no-op token, otherwise `false`.
40
90
 
91
+ ### assertRGXNoOpToken
92
+ ```typescript
93
+ function assertRGXNoOpToken(value: unknown): asserts value is RGXNoOpToken
94
+ ```
95
+
96
+ Asserts that the given value is a no-op token (`null` or `undefined`). If the assertion fails, an `RGXInvalidTokenError` will be thrown.
97
+
98
+ #### Parameters
99
+ - `value` (`unknown`): The value to assert.
100
+
101
+ #### Returns
102
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
103
+
41
104
  ### isRGXLiteralToken
42
105
  ```typescript
43
106
  function isRGXLiteralToken(value: unknown): value is RGXLiteralToken
@@ -51,6 +114,19 @@ Checks if the given value is a literal token (a `RegExp` object).
51
114
  #### Returns
52
115
  - `boolean`: `true` if the value is a literal token, otherwise `false`.
53
116
 
117
+ ### assertRGXLiteralToken
118
+ ```typescript
119
+ function assertRGXLiteralToken(value: unknown): asserts value is RGXLiteralToken
120
+ ```
121
+
122
+ Asserts that the given value is a literal token (a `RegExp` object). If the assertion fails, an `RGXInvalidTokenError` will be thrown.
123
+
124
+ #### Parameters
125
+ - `value` (`unknown`): The value to assert.
126
+
127
+ #### Returns
128
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
129
+
54
130
  ### isRGXNativeToken
55
131
  ```typescript
56
132
  function isRGXNativeToken(value: unknown): value is RGXNativeToken
@@ -64,12 +140,25 @@ Checks if the given value is a native token (string, number, boolean, or no-op).
64
140
  #### Returns
65
141
  - `boolean`: `true` if the value is a native token, otherwise `false`.
66
142
 
143
+ ### assertRGXNativeToken
144
+ ```typescript
145
+ function assertRGXNativeToken(value: unknown): asserts value is RGXNativeToken
146
+ ```
147
+
148
+ Asserts that the given value is a native token (string, number, boolean, or no-op). If the assertion fails, an `RGXInvalidTokenError` will be thrown.
149
+
150
+ #### Parameters
151
+ - `value` (`unknown`): The value to assert.
152
+
153
+ #### Returns
154
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
155
+
67
156
  ### isRGXConvertibleToken
68
157
  ```typescript
69
158
  function isRGXConvertibleToken(value: unknown): value is RGXConvertibleToken
70
159
  ```
71
160
 
72
- Checks if the given value is a convertible token (an object with a `toRgx` method). Validates that `toRgx` is callable and returns a valid RGX native token or array of native tokens.
161
+ Checks if the given value is a convertible token (an object with a `toRgx` method). Validates that `toRgx` is callable and returns a valid RGX native or literal token, or an array of native/literal tokens.
73
162
 
74
163
  #### Parameters
75
164
  - `value` (`unknown`): The value to check.
@@ -77,12 +166,24 @@ Checks if the given value is a convertible token (an object with a `toRgx` metho
77
166
  #### Returns
78
167
  - `boolean`: `true` if the value is a convertible token, otherwise `false`.
79
168
 
169
+ ### assertRGXConvertibleToken
170
+ ```typescript
171
+ function assertRGXConvertibleToken(value: unknown): asserts value is RGXConvertibleToken
172
+ ```
173
+ Asserts that the given value is a convertible token (an object with a `toRgx` method). Validates that `toRgx` is callable and returns a valid RGX native or literal token, or an array of native/literal tokens. If the assertion fails, an `RGXInvalidTokenError` will be thrown.
174
+
175
+ #### Parameters
176
+ - `value` (`unknown`): The value to assert.
177
+
178
+ #### Returns
179
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
180
+
80
181
  ### rgxTokenType
81
182
  ```typescript
82
183
  function rgxTokenType(value: RGXToken): RGXTokenType
83
184
  ```
84
185
 
85
- Determines the type of a given RGX token (`no-op`, `native`, `convertible`, or an array of the former).
186
+ Determines the type of a given RGX token (`no-op`, `literal`, `native`, `convertible`, or an array of the former).
86
187
 
87
188
  If you narrow the result of this function to something more specific, you can then convert these string or array literals into their corresponding token types using the `RGXTokenFromType` utility type or `rgxTokenFromType` function.
88
189
 
@@ -116,9 +217,9 @@ Does nothing at runtime, but performs a type assertion to the correct subset of
116
217
  #### Returns
117
218
  - `RGXTokenFromType<T>`: The input value, but with its type asserted to the corresponding token type based on the provided `RGXTokenType`.
118
219
 
119
- ### isValidRegex
220
+ ### isValidRegexString
120
221
  ```typescript
121
- function isValidRegex(value: string): value is ValidRegexString
222
+ function isValidRegexString(value: string): value is ValidRegexString
122
223
  ```
123
224
 
124
225
  Checks if the given string is a valid regular expression by attempting to create a new `RegExp` object with it. If it succeeds, the string is branded as a `ValidRegexString`.
@@ -129,6 +230,43 @@ Checks if the given string is a valid regular expression by attempting to create
129
230
  #### Returns
130
231
  - `boolean`: `true` if the string is a valid regular expression, otherwise `false`.
131
232
 
233
+ ### assertValidRegexString
234
+ ```typescript
235
+ function assertValidRegexString(value: string): asserts value is ValidRegexString
236
+ ```
237
+ Asserts that the given string is a valid regular expression by attempting to create a new `RegExp` object with it. If it succeeds, the string is branded as a `ValidRegexString`. If the assertion fails, an `RGXInvalidRegexStringError` will be thrown.
238
+
239
+ #### Parameters
240
+ - `value` (`string`): The string to assert.
241
+
242
+ #### Returns
243
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
244
+
245
+ ### isValidVanillaRegexFlags
246
+ ```typescript
247
+ function isValidVanillaRegexFlags(value: string): value is ValidVanillaRegexFlags
248
+ ```
249
+
250
+ Checks if the given string is a valid combination of vanilla regex flags (g, i, m, s, u, y). Each flag can only appear once.
251
+
252
+ #### Parameters
253
+ - `value` (`string`): The string to check.
254
+
255
+ #### Returns
256
+ - `boolean`: `true` if the string is a valid combination of vanilla regex flags, otherwise `false`.
257
+
258
+ ### assertValidVanillaRegexFlags
259
+ ```typescript
260
+ function assertValidVanillaRegexFlags(value: string): asserts value is ValidVanillaRegexFlags
261
+ ```
262
+ Asserts that the given string is a valid combination of vanilla regex flags (g, i, m, s, u, y). Each flag can only appear once. If the assertion fails, an `RGXInvalidVanillaRegexFlagsError` will be thrown.
263
+
264
+ #### Parameters
265
+ - `value` (`string`): The string to assert.
266
+
267
+ #### Returns
268
+ - `void`: This function does not return a value, but will throw an error if the assertion fails.
269
+
132
270
  ### escapeRegex
133
271
  ```typescript
134
272
  function escapeRegex(value: string): ValidRegexString
@@ -170,30 +308,34 @@ A helper function that resolves an array of RGX tokens and concatenates their re
170
308
 
171
309
  ### rgx
172
310
  ```typescript
173
- function rgx(strings: TemplateStringsArray, ...tokens: RGXToken[]): RegExp
311
+ function rgx(flags?: string): (strings: TemplateStringsArray, ...tokens: RGXToken[]) =>RegExp
174
312
  ```
175
313
 
176
- A template tag function that constructs a `RegExp` object from the provided template literal. The template literal can contain RGX tokens, which will be resolved and concatenated with the literal parts to form the final regex pattern.
314
+ Creates and returns a template tag function that constructs a `RegExp` 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.
177
315
 
178
316
  Example usages:
179
317
  ```typescript
180
318
  const beginning = /^/;
181
319
  const end = /$/;
182
320
  const word = /\w+/;
183
- const pattern = rgx`${beginning}testing ${word}${end}`; // /^testing \w+$/ - matches the string "testing " followed by a word, anchored to the start and end of the string
321
+ const pattern = rgx()`${beginning}testing ${word}${end}`; // /^testing \w+$/ - matches the string "testing " followed by a word, anchored to the start and end of the string
184
322
 
185
323
  const optionalDigit = /\d?/;
186
- 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
324
+ 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
187
325
 
188
- 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
326
+ 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
189
327
  ```
190
328
 
191
329
  #### Parameters
330
+ **Direct**
331
+ - `flags` (`string`, optional): The regex flags to apply to the resulting `RegExp` object (e.g., 'g', 'i', 'm', etc.). If not provided, no flags will be applied. If provided and not valid vanilla regex flags, an `RGXError` with code `INVALID_VANILLA_REGEX_FLAGS` will be thrown.
332
+
333
+ **Template Tag**
192
334
  - `strings` (`TemplateStringsArray`): The literal parts of the template string.
193
335
  - `tokens` (`RGXToken[]`): The RGX tokens to be resolved and concatenated with the literal parts.
194
336
 
195
337
  #### Returns
196
- - `RegExp`: The resulting regular expression object constructed from the template literal.
338
+ - `(strings: TemplateStringsArray, ...tokens: RGXToken[]) => RegExp`: A template tag function that takes a template literal and returns a `RegExp` object constructed from the resolved tokens and literal parts.
197
339
 
198
340
  ## Peer Dependencies
199
341
  - `@ptolemy2002/ts-brand-utils` ^1.0.0
@@ -0,0 +1,21 @@
1
+ export type RGXErrorCode = 'UNKNOWN' | 'INVALID_RGX_TOKEN' | 'INVALID_REGEX_STRING' | 'INVALID_VANILLA_REGEX_FLAGS';
2
+ export declare class RGXError extends Error {
3
+ code: RGXErrorCode;
4
+ constructor(message: string, code?: RGXErrorCode);
5
+ }
6
+ export declare class RGXInvalidTokenError extends RGXError {
7
+ expected: string;
8
+ got: unknown;
9
+ constructor(message: string, expected: string | null, got: unknown);
10
+ toString(): string;
11
+ }
12
+ export declare class RGXInvalidRegexStringError extends RGXError {
13
+ got: string;
14
+ constructor(message: string, got: string);
15
+ toString(): string;
16
+ }
17
+ export declare class RGXInvalidVanillaRegexFlagsError extends RGXError {
18
+ got: string;
19
+ constructor(message: string, got: string);
20
+ toString(): string;
21
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RGXInvalidVanillaRegexFlagsError = exports.RGXInvalidRegexStringError = exports.RGXInvalidTokenError = exports.RGXError = void 0;
4
+ class RGXError extends Error {
5
+ constructor(message, code) {
6
+ super(message);
7
+ this.code = 'UNKNOWN';
8
+ this.name = 'RGXError';
9
+ if (code) {
10
+ this.code = code;
11
+ }
12
+ }
13
+ }
14
+ exports.RGXError = RGXError;
15
+ class RGXInvalidTokenError extends RGXError {
16
+ constructor(message, expected, got) {
17
+ super(message, 'INVALID_RGX_TOKEN');
18
+ this.expected = '[null, undefined, string, number, boolean, RegExp, convertible object, or array of native/literal tokens]';
19
+ this.name = 'RGXInvalidTokenError';
20
+ if (expected !== null)
21
+ this.expected = "[" + expected + "]";
22
+ this.got = got;
23
+ }
24
+ toString() {
25
+ return `${this.name}: ${this.message}; Expected: ${this.expected}; Got: ${JSON.stringify(this.got)}`;
26
+ }
27
+ }
28
+ exports.RGXInvalidTokenError = RGXInvalidTokenError;
29
+ class RGXInvalidRegexStringError extends RGXError {
30
+ constructor(message, got) {
31
+ super(message, 'INVALID_REGEX_STRING');
32
+ this.name = 'RGXInvalidRegexStringError';
33
+ this.got = got;
34
+ }
35
+ toString() {
36
+ return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
37
+ }
38
+ }
39
+ exports.RGXInvalidRegexStringError = RGXInvalidRegexStringError;
40
+ class RGXInvalidVanillaRegexFlagsError extends RGXError {
41
+ constructor(message, got) {
42
+ super(message, 'INVALID_VANILLA_REGEX_FLAGS');
43
+ this.name = 'RGXInvalidVanillaRegexFlagsError';
44
+ this.got = got;
45
+ }
46
+ toString() {
47
+ return `${this.name}: ${this.message}; Got: ${JSON.stringify(this.got)}`;
48
+ }
49
+ }
50
+ exports.RGXInvalidVanillaRegexFlagsError = RGXInvalidVanillaRegexFlagsError;
package/dist/index.d.ts CHANGED
@@ -1,27 +1,21 @@
1
- import { Branded } from "@ptolemy2002/ts-brand-utils";
2
- import { MaybeArray } from "@ptolemy2002/ts-utils";
3
- export type RGXNoOpToken = null | undefined;
4
- export type RGXLiteralToken = RegExp;
5
- export type RGXNativeToken = string | number | boolean | RGXNoOpToken;
6
- export type RGXConvertibleToken = {
7
- toRgx: () => MaybeArray<RGXNativeToken | RGXLiteralToken>;
8
- };
9
- export type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
10
- export type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | RGXTokenType[];
11
- export type RGXTokenFromType<T extends RGXTokenType> = T extends 'no-op' ? RGXNoOpToken : T extends 'literal' ? RGXLiteralToken : T extends 'native' ? RGXNativeToken : T extends 'convertible' ? RGXConvertibleToken : T extends RGXTokenType[] ? {
12
- [K in keyof T]: T[K] extends RGXTokenType ? RGXTokenFromType<T[K]> : never;
13
- } : never;
14
- export declare const validRegexSymbol: unique symbol;
15
- export type ValidRegexBrandSymbol = typeof validRegexSymbol;
16
- export type ValidRegexString = Branded<string, [ValidRegexBrandSymbol]>;
17
- export declare function isRGXNoOpToken(value: unknown): value is RGXNoOpToken;
18
- export declare function isRGXLiteralToken(value: unknown): value is RGXLiteralToken;
19
- export declare function isRGXNativeToken(value: unknown): value is RGXNativeToken;
20
- export declare function isRGXConvertibleToken(value: unknown): value is RGXConvertibleToken;
21
- export declare function rgxTokenType(value: RGXToken): RGXTokenType;
22
- export declare function rgxTokenFromType<T extends RGXTokenType>(type: T, value: RGXToken): RGXTokenFromType<T>;
23
- export declare function isValidRegex(value: string): value is ValidRegexString;
24
- export declare function escapeRegex(value: string): ValidRegexString;
25
- export declare function resolveRGXToken(token: RGXToken): ValidRegexString;
26
- export declare function rgxConcat(tokens: RGXToken[]): ValidRegexString;
27
- export default function rgx(strings: TemplateStringsArray, ...tokens: RGXToken[]): RegExp;
1
+ import * as t from "./types";
2
+ export * from "./errors";
3
+ export * from "./types";
4
+ export declare function isRGXNoOpToken(value: unknown): value is t.RGXNoOpToken;
5
+ export declare function assertRGXNoOpToken(value: unknown): asserts value is t.RGXNoOpToken;
6
+ export declare function isRGXLiteralToken(value: unknown): value is t.RGXLiteralToken;
7
+ export declare function assertRGXLiteralToken(value: unknown): asserts value is t.RGXLiteralToken;
8
+ export declare function isRGXNativeToken(value: unknown): value is t.RGXNativeToken;
9
+ export declare function assertRGXNativeToken(value: unknown): asserts value is t.RGXNativeToken;
10
+ export declare function isRGXConvertibleToken(value: unknown): value is t.RGXConvertibleToken;
11
+ export declare function assertRGXConvertibleToken(value: unknown): asserts value is t.RGXConvertibleToken;
12
+ export declare function rgxTokenType(value: t.RGXToken): t.RGXTokenType;
13
+ export declare function rgxTokenFromType<T extends t.RGXTokenType>(type: T, value: t.RGXToken): t.RGXTokenFromType<T>;
14
+ export declare function isValidRegexString(value: string): value is t.ValidRegexString;
15
+ export declare function assertValidRegexString(value: string): asserts value is t.ValidRegexString;
16
+ export declare function isValidVanillaRegexFlags(value: string): value is t.ValidVanillaRegexFlags;
17
+ export declare function assertValidVanillaRegexFlags(value: string): asserts value is t.ValidVanillaRegexFlags;
18
+ export declare function escapeRegex(value: string): t.ValidRegexString;
19
+ export declare function resolveRGXToken(token: t.RGXToken): t.ValidRegexString;
20
+ export declare function rgxConcat(tokens: t.RGXToken[]): t.ValidRegexString;
21
+ export default function rgx(flags?: string): (strings: TemplateStringsArray, ...tokens: t.RGXToken[]) => RegExp;
package/dist/index.js CHANGED
@@ -1,31 +1,90 @@
1
1
  "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
36
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
37
+ };
2
38
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
39
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
40
  };
5
41
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.validRegexSymbol = void 0;
7
42
  exports.isRGXNoOpToken = isRGXNoOpToken;
43
+ exports.assertRGXNoOpToken = assertRGXNoOpToken;
8
44
  exports.isRGXLiteralToken = isRGXLiteralToken;
45
+ exports.assertRGXLiteralToken = assertRGXLiteralToken;
9
46
  exports.isRGXNativeToken = isRGXNativeToken;
47
+ exports.assertRGXNativeToken = assertRGXNativeToken;
10
48
  exports.isRGXConvertibleToken = isRGXConvertibleToken;
49
+ exports.assertRGXConvertibleToken = assertRGXConvertibleToken;
11
50
  exports.rgxTokenType = rgxTokenType;
12
51
  exports.rgxTokenFromType = rgxTokenFromType;
13
- exports.isValidRegex = isValidRegex;
52
+ exports.isValidRegexString = isValidRegexString;
53
+ exports.assertValidRegexString = assertValidRegexString;
54
+ exports.isValidVanillaRegexFlags = isValidVanillaRegexFlags;
55
+ exports.assertValidVanillaRegexFlags = assertValidVanillaRegexFlags;
14
56
  exports.escapeRegex = escapeRegex;
15
57
  exports.resolveRGXToken = resolveRGXToken;
16
58
  exports.rgxConcat = rgxConcat;
17
59
  exports.default = rgx;
18
60
  const is_callable_1 = __importDefault(require("is-callable"));
19
- exports.validRegexSymbol = Symbol('ValidRegex');
61
+ const e = __importStar(require("./errors"));
62
+ __exportStar(require("./errors"), exports);
63
+ __exportStar(require("./types"), exports);
20
64
  function isRGXNoOpToken(value) {
21
65
  return value === null || value === undefined;
22
66
  }
67
+ function assertRGXNoOpToken(value) {
68
+ if (!isRGXNoOpToken(value)) {
69
+ throw new e.RGXInvalidTokenError(`Invalid no-op token`, 'null or undefined', value);
70
+ }
71
+ }
23
72
  function isRGXLiteralToken(value) {
24
73
  return value instanceof RegExp;
25
74
  }
75
+ function assertRGXLiteralToken(value) {
76
+ if (!isRGXLiteralToken(value)) {
77
+ throw new e.RGXInvalidTokenError(`Invalid literal token`, 'RegExp', value);
78
+ }
79
+ }
26
80
  function isRGXNativeToken(value) {
27
81
  return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' || isRGXNoOpToken(value);
28
82
  }
83
+ function assertRGXNativeToken(value) {
84
+ if (!isRGXNativeToken(value)) {
85
+ throw new e.RGXInvalidTokenError(`Invalid native token`, 'string, number, boolean, null, or undefined', value);
86
+ }
87
+ }
29
88
  function isRGXConvertibleToken(value) {
30
89
  if (typeof value === 'object' && value !== null && 'toRgx' in value) {
31
90
  if ((0, is_callable_1.default)(value.toRgx)) {
@@ -39,6 +98,11 @@ function isRGXConvertibleToken(value) {
39
98
  }
40
99
  return false;
41
100
  }
101
+ function assertRGXConvertibleToken(value) {
102
+ if (!isRGXConvertibleToken(value)) {
103
+ throw new e.RGXInvalidTokenError(`Invalid convertible token`, 'object with a toRgx method that returns a valid token', value);
104
+ }
105
+ }
42
106
  function rgxTokenType(value) {
43
107
  if (isRGXNoOpToken(value))
44
108
  return 'no-op';
@@ -52,14 +116,14 @@ function rgxTokenType(value) {
52
116
  return value.map(rgxTokenType);
53
117
  // Ignoring this line since it should be impossible to reach if the types are correct, but we need it to satisfy the return type
54
118
  /* istanbul ignore next */
55
- throw new TypeError(`Invalid RGX token: ${value}`);
119
+ throw new e.RGXInvalidTokenError(`Invalid RGX token: ${value}`, null, value);
56
120
  }
57
121
  function rgxTokenFromType(type, value) {
58
122
  // Ignoring this line because the function is entirely a TypeScript utility that doesn't need to be tested at runtime.
59
123
  /* istanbul ignore next */
60
124
  return value;
61
125
  }
62
- function isValidRegex(value) {
126
+ function isValidRegexString(value) {
63
127
  try {
64
128
  new RegExp(value);
65
129
  return true;
@@ -68,6 +132,24 @@ function isValidRegex(value) {
68
132
  return false;
69
133
  }
70
134
  }
135
+ function assertValidRegexString(value) {
136
+ if (!isValidRegexString(value)) {
137
+ throw new e.RGXInvalidRegexStringError(`Invalid regex string: ${value}`, value);
138
+ }
139
+ }
140
+ function isValidVanillaRegexFlags(value) {
141
+ const patternMatch = /^[gimsuy]*$/.test(value);
142
+ if (!patternMatch)
143
+ return false;
144
+ // No repeated flags allowed
145
+ const flagsSet = new Set(value);
146
+ return flagsSet.size === value.length;
147
+ }
148
+ function assertValidVanillaRegexFlags(value) {
149
+ if (!isValidVanillaRegexFlags(value)) {
150
+ throw new e.RGXInvalidVanillaRegexFlagsError(`Invalid vanilla regex flags: ${value}`, value);
151
+ }
152
+ }
71
153
  function escapeRegex(value) {
72
154
  return value.replaceAll(/[\-\^\$.*+?^${}()|[\]\\]/g, '\\$&');
73
155
  }
@@ -92,20 +174,23 @@ function resolveRGXToken(token) {
92
174
  }
93
175
  // Ignoring this line since it should be impossible to reach if the types are correct, but we need it to satisfy the return type
94
176
  /* istanbul ignore next */
95
- throw new TypeError(`Invalid RGX token: ${token}`);
177
+ throw new e.RGXInvalidTokenError(`Invalid RGX token: ${token}`, null, token);
96
178
  }
97
179
  // Wrapper for letting an array of tokens be resolved as a concatenation instead of a union.
98
180
  function rgxConcat(tokens) {
99
181
  return tokens.map(resolveRGXToken).join('');
100
182
  }
101
- function rgx(strings, ...tokens) {
102
- let pattern = '';
103
- const resolvedTokens = tokens.map(resolveRGXToken);
104
- for (let i = 0; i < strings.length; i++) {
105
- pattern += strings[i];
106
- if (i < resolvedTokens.length) {
107
- pattern += resolvedTokens[i];
183
+ function rgx(flags = '') {
184
+ assertValidVanillaRegexFlags(flags);
185
+ return (strings, ...tokens) => {
186
+ let pattern = '';
187
+ const resolvedTokens = tokens.map(resolveRGXToken);
188
+ for (let i = 0; i < strings.length; i++) {
189
+ pattern += strings[i];
190
+ if (i < resolvedTokens.length) {
191
+ pattern += resolvedTokens[i];
192
+ }
108
193
  }
109
- }
110
- return new RegExp(pattern);
194
+ return new RegExp(pattern, flags);
195
+ };
111
196
  }
@@ -0,0 +1,19 @@
1
+ import { Branded } from "@ptolemy2002/ts-brand-utils";
2
+ import { MaybeArray } from "@ptolemy2002/ts-utils";
3
+ export type RGXNoOpToken = null | undefined;
4
+ export type RGXLiteralToken = RegExp;
5
+ export type RGXNativeToken = string | number | boolean | RGXNoOpToken;
6
+ export type RGXConvertibleToken = {
7
+ toRgx: () => MaybeArray<RGXNativeToken | RGXLiteralToken>;
8
+ };
9
+ export type RGXToken = RGXNativeToken | RGXLiteralToken | RGXConvertibleToken | RGXToken[];
10
+ export type RGXTokenType = 'no-op' | 'literal' | 'native' | 'convertible' | RGXTokenType[];
11
+ export type RGXTokenFromType<T extends RGXTokenType> = T extends 'no-op' ? RGXNoOpToken : T extends 'literal' ? RGXLiteralToken : T extends 'native' ? RGXNativeToken : T extends 'convertible' ? RGXConvertibleToken : T extends RGXTokenType[] ? {
12
+ [K in keyof T]: T[K] extends RGXTokenType ? RGXTokenFromType<T[K]> : never;
13
+ } : never;
14
+ export declare const validRegexSymbol: unique symbol;
15
+ export type ValidRegexBrandSymbol = typeof validRegexSymbol;
16
+ export type ValidRegexString = Branded<string, [ValidRegexBrandSymbol]>;
17
+ export declare const validVanillaRegexFlagsSymbol: unique symbol;
18
+ export type ValidVanillaRegexFlagsBrandSymbol = typeof validVanillaRegexFlagsSymbol;
19
+ export type ValidVanillaRegexFlags = Branded<string, [ValidVanillaRegexFlagsBrandSymbol]>;
package/dist/types.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validVanillaRegexFlagsSymbol = exports.validRegexSymbol = void 0;
4
+ exports.validRegexSymbol = Symbol('rgx.ValidRegex');
5
+ exports.validVanillaRegexFlagsSymbol = Symbol('rgx.ValidVanillaRegexFlags');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ptolemy2002/rgx",
3
- "version": "1.2.0",
3
+ "version": "2.0.1",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",