literate-regex 0.6.2 → 0.6.9

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/dist/cjs/index.js CHANGED
@@ -38,4 +38,4 @@ const compilePCREStyleRegExpLiteral = (src) => {
38
38
  return new RegExp(pattern, flags);
39
39
  };
40
40
  exports.compilePCREStyleRegExpLiteral = compilePCREStyleRegExpLiteral;
41
- exports.version = "v0.6.2";
41
+ exports.version = "v0.6.9";
@@ -32,4 +32,4 @@ export const compilePCREStyleRegExpLiteral = (src) => {
32
32
  const { pattern, flags } = extractJsRegexPartsFromPCREStyleRegExpLiteral(src);
33
33
  return new RegExp(pattern, flags);
34
34
  };
35
- export const version = "v0.6.2";
35
+ export const version = "v0.6.9";
package/dist/global.d.ts CHANGED
@@ -18,6 +18,7 @@
18
18
  */
19
19
  import type {
20
20
  TypedRegExp,
21
+ TypedRegExpCore,
21
22
  StringReplacerType,
22
23
  RegExpExecArrayFixedPretty,
23
24
  } from "./index.d.ts";
@@ -31,7 +32,7 @@ declare global {
31
32
  * @param {string} str The String object or string literal on which to perform the search.
32
33
  * @returns {RegExpExecArrayFixedPretty< this > | null} An array of results or null if no match is found.
33
34
  */
34
- exec<const P extends string, const F extends string = "", This extends RegExp = TypedRegExp<P, F>>(this: This, str: string): RegExpExecArrayFixedPretty< This > | null;
35
+ exec<const P extends string, const F extends string = "", This extends RegExp = TypedRegExpCore<P, F>>(this: This, str: string): RegExpExecArrayFixedPretty< This > | null;
35
36
  }
36
37
  interface String {
37
38
  /**
@@ -40,7 +41,7 @@ declare global {
40
41
  * @param searchValue A regular expression object.
41
42
  * @param replaceValue A string or a function to create the new substring.
42
43
  */
43
- replace<SV extends RegExp | string>(this: string, searchValue: SV, replaceValue: StringReplacerType<SV>): string;
44
+ replace<SV extends RegExp>(this: string, searchValue: SV, replaceValue: StringReplacerType<SV>): string;
44
45
  }
45
46
  interface RegExpConstructor {
46
47
  /**
package/dist/index.d.ts CHANGED
@@ -19,6 +19,7 @@
19
19
  */
20
20
  export * from "./types/common";
21
21
  export * from "./types/regex";
22
+ export * from "./types/regex-util";
22
23
  export * from "./types/pcre";
23
24
  export * from "./types/captures";
24
25
  export * from "./types/parser";
@@ -20,9 +20,9 @@ import type {
20
20
  TupleOf,
21
21
  IsEmptyRecord,
22
22
  } from "./common.d.ts";
23
- import type { RegExpSource } from "./regex.d.ts";
24
23
  import type {
25
24
  RegExpFlags,
25
+ RegExpSource,
26
26
  HasStrictRegExpFlag,
27
27
  } from "./regex-util.d.ts";
28
28
  /*!
@@ -30,7 +30,10 @@ import type {
30
30
  // Named Capture Groups
31
31
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
32
32
  */
33
- type FirstChar<S extends string> = S extends `${infer F}${infer _}` ? F : never;
33
+ /**
34
+ * @internal
35
+ */
36
+ export type FirstChar<S extends string> = S extends `${infer F}${infer _}` ? F : never;
34
37
  /**
35
38
  * Recursively extracts parts that match the format (?<GroupName>...) from a string pattern,
36
39
  * without considering nesting, and unions them.
@@ -131,17 +134,17 @@ export type CaptureOptTuple<N extends number, T = string | undefined> =
131
134
  /**
132
135
  * @internal
133
136
  */
134
- type TIndicesItem = [index: number, lastIndex: number];
137
+ export type TIndicesItem = [index: number, lastIndex: number];
135
138
  /**
136
139
  * @internal
137
140
  */
138
- type RegExpIndicesGroups<NamedGroups> = IsEmptyRecord<NamedGroups> extends true
141
+ export type RegExpIndicesGroups<NamedGroups> = IsEmptyRecord<NamedGroups> extends true
139
142
  ? undefined
140
143
  : { [P in keyof NamedGroups & string]: TIndicesItem | undefined };
141
144
  /**
142
145
  * @internal
143
146
  */
144
- type RegExpIndicesTuple<GroupCount extends number> = [
147
+ export type RegExpIndicesTuple<GroupCount extends number> = [
145
148
  match: TIndicesItem,
146
149
  ...BuildCaptureTuple<GroupCount, TIndicesItem | undefined>
147
150
  ];
@@ -183,6 +186,11 @@ export type RegExpExecArrayFixed<
183
186
  GroupCount extends number = CountCaptureGroups<S>,
184
187
  NamedGroups = RegExpNamedGroups<R>
185
188
  > = RegExpExecArrayFixedBase<R, GroupCount, NamedGroups>;
189
+ /**
190
+ * Represents a fixed version of RegExpExecArray that includes the matched string,
191
+ * captures (with named parameters for better readability), and optionally named groups.
192
+ * @template R - A RegExp type.
193
+ */
186
194
  export type RegExpExecArrayFixedPretty<
187
195
  R extends RegExp,
188
196
  S extends RegExpSource<R> = RegExpSource<R>,
@@ -16,12 +16,34 @@
16
16
  /**
17
17
  * @file types/common.d.ts
18
18
  */
19
+ /**
20
+ * Combines an intersection of object types into a single object type.
21
+ *
22
+ * @template IS The intersection of object types to combine.
23
+ * @returns {Record<string, unknown>} A single object type with all properties from the intersection.
24
+ *
25
+ * @example
26
+ * type Combined = CombineIntersection<{ a: string } & { b: number }>;
27
+ * // Result: { a: string; b: number }
28
+ */
29
+ export type CombineIntersection<IS> =
30
+ true extends 0 ? { [K in keyof IS]: IS[K] } : { [K in keyof IS]: IS[K] };
31
+ /**
32
+ * Creates a tuple type of a specified length, with all elements being of a given type.
33
+ * @template Count - The desired length of the tuple.
34
+ * @template ArrayType - The type of each element in the tuple.
35
+ */
19
36
  export type TupleOf<
20
37
  Count extends number, ArrayType,
21
38
  Result extends ArrayType[] = []
22
39
  > = Result["length"] extends Count
23
40
  ? Result
24
41
  : TupleOf<Count, ArrayType, [...Result, ArrayType]>;
42
+ /**
43
+ * Checks if a given type `T` represents an empty record or `undefined`.
44
+ * @template T - The type to check.
45
+ * @returns `true` if `T` is `undefined` or has no keys, otherwise `false`.
46
+ */
25
47
  export type IsEmptyRecord<T> =
26
48
  [T] extends [undefined] ? true :
27
49
  [keyof T] extends [never] ? true : false;
@@ -24,9 +24,25 @@ import type { PCREStyleToJsRegExpSource } from "./pcre.d.ts";
24
24
  // Parse PCRE Style Regex Literal
25
25
  // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
26
26
  */
27
+ /**
28
+ * Represents the complete set of valid JavaScript regular expression flags.
29
+ * This type is a string literal containing all possible flags: `d`, `g`, `i`, `m`, `s`, `u`, `v`, `y`.
30
+ */
27
31
  export type TRegexpFlag = "dgimsuvy";
32
+ /**
33
+ * Represents a union of individual valid JavaScript regular expression flags,
34
+ * including an empty string for cases where no flag is present.
35
+ */
28
36
  export type TValidRegExpFlag = StringToUnion<TRegexpFlag> | "";
29
- type StripFlagsFromEnd<S extends string, Acc extends string = ""> =
37
+ /**
38
+ * Recursively strips valid RegExp flags from the end of a string literal.
39
+ * This type is designed to avoid TypeScript's backtracking limitations by processing one character at a time.
40
+ *
41
+ * @template S - The input string literal from which to strip flags.
42
+ * @template Acc - An accumulator for the stripped flags, built in reverse order.
43
+ * @internal
44
+ */
45
+ export type StripFlagsFromEnd<S extends string, Acc extends string = ""> =
30
46
  S extends `${infer Rest}y` ? StripFlagsFromEnd<Rest, `y${Acc}`> :
31
47
  S extends `${infer Rest}v` ? StripFlagsFromEnd<Rest, `v${Acc}`> :
32
48
  S extends `${infer Rest}u` ? StripFlagsFromEnd<Rest, `u${Acc}`> :
@@ -35,6 +51,12 @@ type StripFlagsFromEnd<S extends string, Acc extends string = ""> =
35
51
  S extends `${infer Rest}i` ? StripFlagsFromEnd<Rest, `i${Acc}`> :
36
52
  S extends `${infer Rest}g` ? StripFlagsFromEnd<Rest, `g${Acc}`> :
37
53
  S extends `${infer Rest}d` ? StripFlagsFromEnd<Rest, `d${Acc}`> : { body: S; flags: Acc };
54
+ /**
55
+ * Extracts the pattern and flags from a JavaScript-style regular expression literal string (e.g., `/pattern/flags`).
56
+ *
57
+ * @template L - The RegExp literal string.
58
+ * @returns An object type with `pattern` and `flags` properties.
59
+ */
38
60
  export type RegExpLiteralParts<L extends string> =
39
61
  StripFlagsFromEnd<L> extends { body: infer B extends string; flags: infer F extends string }
40
62
  ? B extends `/${infer AfterStart}`
@@ -43,9 +65,32 @@ export type RegExpLiteralParts<L extends string> =
43
65
  : never
44
66
  : never
45
67
  : never;
68
+ /**
69
+ * Extracts the pattern and flags from a PCRE-style regular expression literal string,
70
+ * after it has been normalized to a JavaScript-style literal.
71
+ *
72
+ * @template S - The PCRE-style RegExp literal string.
73
+ * @returns An object type with `pattern` and `flags` properties.
74
+ */
46
75
  export type PCREStyleRegExpParts<S extends string> = RegExpLiteralParts<PCREStyleToJsRegExpSource<S>>;
76
+ /**
77
+ * Extracts the pattern string from a PCRE-style regular expression literal.
78
+ *
79
+ * @template S - The PCRE-style RegExp literal string.
80
+ */
47
81
  export type PCREStyleRegExpPattern<S extends string> = PCREStyleRegExpParts<S>["pattern"];
82
+ /**
83
+ * Extracts the flags string from a PCRE-style regular expression literal.
84
+ *
85
+ * @template S - The PCRE-style RegExp literal string.
86
+ */
48
87
  export type PCREStyleRegExpFlags<S extends string> = PCREStyleRegExpParts<S>["flags"];
88
+ /**
89
+ * Extracts the pattern and flags from a PCRE-style regular expression literal string at runtime.
90
+ *
91
+ * @template S - The PCRE-style RegExp literal string.
92
+ * @param src - The PCRE-style regular expression literal string.
93
+ */
49
94
  export declare const extractJsRegexPartsFromPCREStyleRegExpLiteral: <const S extends string>(src: S) => PCREStyleRegExpParts<S>;
50
95
  export declare const compilePCREStyleRegExpLiteral: <
51
96
  const S extends string,
@@ -48,12 +48,13 @@
48
48
  /**
49
49
  * Union of whitespace characters used by this library.
50
50
  *
51
- * + A set aligned with ECMAScript RegExp **`\s`** (WhiteSpaceLineTerminator)
51
+ * + A set aligned with ECMAScript RegExp **`\s`** (__WhiteSpaceLineTerminator__)
52
52
  *
53
53
  * The union is used to normalize "PCRE-style" regex sources at the type level.
54
+ *
54
55
  * @internal
55
56
  */
56
- type TWhiteSpace =
57
+ export type TWhiteSpace =
57
58
  | "\x09"
58
59
  | "\x0A"
59
60
  | "\x0B"
@@ -76,6 +77,18 @@ type TWhiteSpace =
76
77
  | "\u2028" | "\u2029"
77
78
  | "\u202F" | "\u205F" | "\u3000"
78
79
  | "\uFEFF";
80
+ /**
81
+ * A looser definition of whitespace characters compared to {@link TWhiteSpace}.
82
+ * This type is used internally for certain normalization processes where a more restricted set of whitespace is considered.
83
+ * @internal
84
+ */
85
+ export type TWhiteSpaceLoose =
86
+ | "\x09"
87
+ | "\x0A"
88
+ | "\x0B"
89
+ | "\x0C"
90
+ | "\x0D"
91
+ | "\x20"
79
92
  /**
80
93
  * Normalize newline sequences for line-based parsing.
81
94
  *
@@ -115,17 +128,17 @@ type NormalizeNewlines<S extends string> =
115
128
  * - Handle `\\#` (a literal backslash + literal #) more strictly.
116
129
  * - Do not treat `#` as a comment starter inside character classes (`[...]`).
117
130
  */
118
- type StripLine<S extends string, Acc extends string = ""> =
131
+ type StripLine<S extends string, WS extends TWhiteSpace = TWhiteSpace, Acc extends string = ""> =
119
132
  S extends `\\#${infer Rest}`
120
- ? StripLine<Rest, `${Acc}#`>
133
+ ? StripLine<Rest, WS, `${Acc}#`>
121
134
  : S extends `\\${infer C}${infer Rest}`
122
- ? StripLine<Rest, `${Acc}\\${C}`>
135
+ ? StripLine<Rest, WS, `${Acc}\\${C}`>
123
136
  : S extends `#${string}`
124
137
  ? Acc
125
138
  : S extends `${infer C}${infer Rest}`
126
- ? C extends TWhiteSpace
127
- ? StripLine<Rest, Acc>
128
- : StripLine<Rest, `${Acc}${C}`>
139
+ ? C extends WS
140
+ ? StripLine<Rest, WS, Acc>
141
+ : StripLine<Rest, WS, `${Acc}${C}`>
129
142
  : Acc;
130
143
  /**
131
144
  * Convert a multi-line PCRE-style regex source into a compact JS `RegExp.source`.
@@ -150,11 +163,18 @@ type StripLine<S extends string, Acc extends string = ""> =
150
163
  */
151
164
  export type PCREStyleToJsRegExpSource<
152
165
  Input extends string,
166
+ WS extends string = TWhiteSpace,
153
167
  Acc extends string = "",
154
168
  S extends string = NormalizeNewlines<Input>,
155
169
  > =
156
170
  S extends `${infer Line}\n${infer Rest}`
157
- ? PCREStyleToJsRegExpSource<Input, `${Acc}${StripLine<Line>}`, Rest>
171
+ ? PCREStyleToJsRegExpSource<Input, WS, `${Acc}${StripLine<Line>}`, Rest>
158
172
  : `${Acc}${StripLine<S>}`;
173
+ /**
174
+ * Normalizes a PCRE-style regular expression source string by removing comments and whitespace.
175
+ * This function is intended for use at runtime.
176
+ *
177
+ * @param src The PCRE-style regular expression source string.
178
+ */
159
179
  export declare const normalizePCREStyleSource: <const S extends string>(src: S) => PCREStyleToJsRegExpSource<S>;
160
180
  export {};
@@ -17,26 +17,49 @@
17
17
  * @file types/regex-util.d.ts
18
18
  */
19
19
  import type {
20
- StringLength,
21
- StringToUnion,
20
+ StringLength, StringToUnion
22
21
  } from "./common.d.ts";
23
22
  import type {
24
- TRegexpFlag,
25
- TValidRegExpFlag,
23
+ TRegexpFlag, TValidRegExpFlag
26
24
  } from "./parser.d.ts";
25
+ /**
26
+ * Extracts the literal type from the source property of a RegExp.
27
+ * @template R - A RegExp type.
28
+ */
29
+ export type RegExpSource<R extends RegExp> = R extends RegExp & { readonly source: infer T } ? T : never;
30
+ /**
31
+ * Extracts the literal type from the flags property of a RegExp.
32
+ * @template R - A RegExp type.
33
+ */
34
+ export type RegExpFlags<R extends RegExp> =
35
+ R extends RegExp & { readonly flags: infer F extends string }
36
+ ? ValidateFlags<F> extends true
37
+ ? F : string
38
+ : string;
27
39
  /**
28
40
  * @internal
29
41
  */
30
42
  type ExceedsMaxRegExpFlagCount<N extends number> =
31
43
  number extends N ? boolean : N extends 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 ? false : true;
32
- /**
33
- * @internal
44
+ /**
45
+ * Checks if all characters in a string `S` are unique.
46
+ *
47
+ * @template S - The input string.
48
+ * @template Seen - An accumulator for characters encountered so far.
49
+ * @returns `true` if all characters in `S` are unique, `false` otherwise.
50
+ * @internal
34
51
  */
35
52
  type IsUniqueChars<S extends string, Seen extends string = never> =
36
53
  S extends `${infer H}${infer T}`
37
54
  ? H extends Seen ? false : IsUniqueChars<T, Seen | H>
38
55
  : true;
39
56
  /**
57
+ * Normalizes a string of RegExp flags by sorting them into a predefined order (`dgimsuvy`).
58
+ * This type is used internally after flags have been validated for uniqueness and allowed characters.
59
+ *
60
+ * @template F - The input string of flags to normalize.
61
+ * @template Order - The desired order of flags (defaults to `TRegexpFlag`).
62
+ * @template Out - An accumulator for the normalized flags.
40
63
  * @internal
41
64
  */
42
65
  type NormalizeFlags<
@@ -45,6 +68,12 @@ type NormalizeFlags<
45
68
  ? NormalizeFlags<
46
69
  F, Rest, F extends `${string}${C}${string}` ? `${Out}${C}` : Out
47
70
  > : Out;
71
+ /**
72
+ * Canonicalizes a string of RegExp flags by validating them, removing duplicates,
73
+ * and sorting them into a predefined order (`dgimsuvy`).
74
+ *
75
+ * @template F - The input string of flags.
76
+ */
48
77
  export type CanonicalFlags<F extends string> =
49
78
  [string] extends [F] ? string :
50
79
  Exclude<StringToUnion<F>, TValidRegExpFlag> extends never
@@ -54,26 +83,43 @@ export type CanonicalFlags<F extends string> =
54
83
  : NormalizeFlags<F>
55
84
  : never
56
85
  : never;
86
+ /**
87
+ * Checks if a string of RegExp flags is "strict", meaning it contains only valid, unique, and non-excessive flags.
88
+ *
89
+ * @template F - The input string of flags.
90
+ * @returns `true` if the flags are strict, `false` otherwise.
91
+ * @internal
92
+ */
57
93
  export type IsStrictFlags<F extends string> =
58
94
  CanonicalFlags<F> extends never ? false : true;
59
- type ValidateFlags<F extends string, Seen extends string = ""> =
95
+ /**
96
+ * Validates a string of RegExp flags for correctness, including uniqueness and allowed characters.
97
+ * This type performs a strict validation, ensuring that each flag is valid and appears only once.
98
+ *
99
+ * @template F - The input string of flags to validate.
100
+ * @template Seen - An accumulator for flags encountered so far (used internally to check for duplicates).
101
+ * @returns `true` if the flags are valid and unique, `false` otherwise.
102
+ * @internal
103
+ */
104
+ export type ValidateFlags<F extends string, Seen extends string = ""> =
60
105
  F extends ""
61
106
  ? true
62
107
  : IsStrictFlags<F> extends false
63
108
  ? false
64
- : F extends `${infer C}${infer Rest}`
65
- ? C extends TValidRegExpFlag
66
- ? C extends Seen
109
+ : F extends `${infer OneCh}${infer Rest}`
110
+ ? OneCh extends TValidRegExpFlag
111
+ ? OneCh extends Seen
67
112
  ? false
68
- : ValidateFlags<Rest, `${Seen}${C}`>
113
+ : ValidateFlags<Rest, `${Seen}${OneCh}`>
69
114
  : false
70
115
  : false;
71
- export type RegExpFlags<R extends RegExp> =
72
- R extends RegExp & { readonly flags: infer F extends string }
73
- ? ValidateFlags<F> extends true
74
- ? F : string
75
- : string;
76
116
  /**
117
+ * Checks if a given RegExp flag string `F` contains a specific flag character `C`.
118
+ * This type performs a strict validation of `F` first.
119
+ *
120
+ * @template F - The input string of RegExp flags.
121
+ * @template C - The specific flag character to check for (e.g., `"g"`, `"i"`).
122
+ * @returns `true` if `F` is valid and contains `C`, `false` otherwise.
77
123
  * @internal
78
124
  */
79
125
  export type HasStrictRegExpFlag<F extends string, C extends TValidRegExpFlag> =
@@ -16,50 +16,57 @@
16
16
  /**
17
17
  * @file types/regex.d.ts
18
18
  */
19
+ import type { CombineIntersection } from "./common.d.ts";
19
20
  import type {
20
21
  CountCaptureGroups,
21
22
  RegExpNamedGroups,
22
23
  RegExpIndicesArray,
23
24
  RegExpExecArrayFixedPretty,
24
25
  } from "./captures.d.ts";
25
- import type { RegExpFlags, HasStrictRegExpFlag } from "./regex-util.d.ts";
26
- import type { StringReplacerType } from "./replacer.d.ts";
26
+ import type {
27
+ RegExpFlags, RegExpSource, HasStrictRegExpFlag
28
+ } from "./regex-util.d.ts";
29
+ import type {
30
+ StringReplacerParams,
31
+ } from "./replacer.d.ts";
27
32
  declare const __typedRegExpBrand: unique symbol;
28
33
  /**
29
34
  * DO NOT USE CONSUMER
30
35
  * @internal
31
36
  */
32
- type TypedRegExpBrand = { readonly [__typedRegExpBrand]: true };
37
+ export type TypedRegExpBrand = { readonly [__typedRegExpBrand]: true };
33
38
  /**
34
39
  * + v0.3.0 feature
40
+ *
41
+ * Represents the detailed type information extracted from a `TypedRegExp` instance.
42
+ * This includes types for named capture groups, `exec` method results,
43
+ * `replace` method replacer functions, and `indices` array (if the 'd' flag is present).
35
44
  *
36
45
  * @since v0.3.0
37
46
  */
38
47
  export type TypedRegExpTypes<
39
48
  R extends RegExp,
40
- S extends RegExpSource<R> = RegExpSource<R>,
49
+ SOURCE extends RegExpSource<R> = RegExpSource<R>,
50
+ FLAGS extends RegExpFlags<R> = RegExpFlags<R>,
41
51
  NamedGroups = RegExpNamedGroups<R>,
42
- GroupCount extends number = CountCaptureGroups<S>,
52
+ GroupCount extends number = CountCaptureGroups<SOURCE>,
43
53
  IsTypedRegExp = R extends TypedRegExpBrand ? true : false,
44
54
  GROUPS = true extends IsTypedRegExp ? NamedGroups : never,
45
- EXEC = true extends IsTypedRegExp ? RegExpExecArrayFixedPretty<R, S, GroupCount, NamedGroups> : never,
46
- REPLACER = true extends IsTypedRegExp ? StringReplacerType<R> : never,
55
+ EXEC = true extends IsTypedRegExp ? RegExpExecArrayFixedPretty<R, SOURCE, GroupCount, NamedGroups> : never,
56
+ REPLACER = true extends IsTypedRegExp ? (...args: StringReplacerParams<TypedRegExpCore<SOURCE, FLAGS>>) => string : never,
47
57
  INDICES = true extends IsTypedRegExp ? RegExpIndicesArray<GroupCount, NamedGroups> : never,
48
58
  > = true extends IsTypedRegExp ? {
49
59
  groups: GROUPS;
50
60
  exec: EXEC | null;
51
61
  replacer: REPLACER;
52
- indices: HasStrictRegExpFlag<RegExpFlags<R>, "d"> extends true ? INDICES : never;
62
+ indices: HasStrictRegExpFlag<FLAGS, "d"> extends true ? INDICES : never;
63
+ typeSystemMessage: "healthy";
53
64
  } : never;
54
65
  /**
55
- * @since 2025/12/24 12:27:39
56
- * @commit js-dev-tool@6ff89180acfb53c1a0bf9aebadfa12b210bfb3f8
66
+ * Watch the regex flags (If flags are statically defined, the state of the flag is bound)
57
67
  */
58
- export type TypedRegExp<P extends string, F extends string = ""> = RegExp & {
59
- readonly source: P;
60
- readonly flags: F;
61
- } & TypedRegExpBrand & {
62
- types: TypedRegExpTypes<TypedRegExp<P, F>>;
68
+ export type RegExpFlagPart<R extends RegExp> = Pick<R, "global" | "dotAll" | "hasIndices" | "ignoreCase" | "multiline" | "sticky" | "unicode" | "unicodeSets">;
69
+ export type TypedRegExpFlagPart<F extends string> = {
63
70
  global: HasStrictRegExpFlag<F, "g">;
64
71
  dotAll: HasStrictRegExpFlag<F, "s">;
65
72
  hasIndices: HasStrictRegExpFlag<F, "d">;
@@ -70,12 +77,64 @@ export type TypedRegExp<P extends string, F extends string = ""> = RegExp & {
70
77
  unicodeSets: HasStrictRegExpFlag<F, "v">;
71
78
  };
72
79
  /**
73
- * Extracts the literal type from the source property of a RegExp.
74
- * @template R - A RegExp type.
80
+ * Represents the combined properties of a `TypedRegExp` instance,
81
+ * including its detailed type information (`types`) and type-level flag properties.
82
+ *
83
+ * @template P - The pattern string of the RegExp.
84
+ * @template F - The flags string of the RegExp.
85
+ * @returns A type that combines `TypedRegExpTypes` and `TypedRegExpFlagPart`.
86
+ * @internal
87
+ */
88
+ export type TypedRegExpProperties<
89
+ P extends string, F extends string = "",
90
+ > = [F] extends [never]
91
+ ? CombineIntersection<{ types: never; } & TypedRegExpFlagPart<F>/*, {}*/>
92
+ : CombineIntersection<{ types: TypedRegExpTypes<TypedRegExpCore<P, F>> } & TypedRegExpFlagPart<F>/*, {}*/>;
93
+ /*!
94
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
95
+ // Primary Types
96
+ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
97
+ */
98
+ /**
99
+ * __`TypedRegExp` base type (core)__
100
+ *
101
+ * + Can extend extra props from this type
102
+ *
103
+ * @template P - The literal type of the regular expression pattern.
104
+ * @template F - The literal type of the regular expression flags.
105
+ * @property {P} source - The literal pattern string of the regular expression.
106
+ * @property {F} flags - The literal flags string of the regular expression.
107
+ * @internal
108
+ */
109
+ export type TypedRegExpCore<P extends string, F extends string = ""> = RegExp & {
110
+ readonly source: P;
111
+ readonly flags: F;
112
+ } & TypedRegExpBrand;
113
+ /**
114
+ * Represents a regular expression with enhanced type information,
115
+ * including literal types for its pattern and flags, and detailed types
116
+ * for its `exec` method results, named capture groups, and replacer functions.
117
+ *
118
+ * @template P - The literal type of the regular expression pattern.
119
+ * @template F - The literal type of the regular expression flags.
120
+ *
121
+ * @since 2025/12/24 12:27:39
122
+ * @commit js-dev-tool@6ff89180acfb53c1a0bf9aebadfa12b210bfb3f8
75
123
  */
76
- export type RegExpSource<R extends RegExp> = R extends RegExp & { readonly source: infer T } ? T : never;
124
+ export type TypedRegExp<
125
+ P extends string,
126
+ F extends string = "",
127
+ > = TypedRegExpCore<P, F> & TypedRegExpProperties<P, F>;
77
128
  /**
78
- * @deprecated description
129
+ * ### __`Type-only signature`__: no runtime implementation is provided.
130
+ *
131
+ * Creates a TypedRegExp type from a pattern and optional flags.
132
+ *
133
+ * @template P - The regex pattern (string literal).
134
+ * @template F - The regex flags (string literal).
135
+ * @param pattern The regex pattern.
136
+ * @param flags Optional regex flags.
137
+ * @see {@link TypedRegExp}
79
138
  */
80
139
  export declare function createRegExp<
81
140
  const P extends string,
@@ -16,10 +16,8 @@
16
16
  /**
17
17
  * @file types/replacer.d.ts
18
18
  */
19
- import type {
20
- TypedRegExp,
21
- RegExpSource,
22
- } from "./regex.d.ts";
19
+ import type { TypedRegExp } from "./regex.d.ts";
20
+ import type { RegExpSource } from "./regex-util.d.ts";
23
21
  import type { IsEmptyRecord } from "./common.d.ts";
24
22
  import type { CountCaptureGroups, RegExpNamedGroups, CaptureOptTuple } from "./captures.d.ts";
25
23
  /*!
@@ -28,36 +26,62 @@ import type { CountCaptureGroups, RegExpNamedGroups, CaptureOptTuple } from "./c
28
26
  // ============================================================================
29
27
  */
30
28
  /**
31
- * Creates the parameter types for String.replace callback function.
32
- *
33
- * @example
34
- * type Params = StringReplacerParams<typeof myRegex>;
35
- * // [match: string, ...captures: string[], offset: number, string: string, groups?: {...}]
29
+ * Represents the rest parameters for the `String.prototype.replace()` replacer function,
30
+ * excluding the `match` parameter.
31
+ *
32
+ * @template R - The `RegExp` type.
33
+ * @template S - The source string of the `RegExp`.
34
+ * @template GroupCount - The number of capture groups in the `RegExp`.
35
+ * @template NamedGroups - The type of named capture groups in the `RegExp`.
36
+ * @returns A tuple type representing the rest parameters of the replacer function.
36
37
  */
37
- export type StringReplacerParams<
38
+ export type StringReplacerRestArgs<
38
39
  R extends RegExp,
39
40
  S extends RegExpSource<R> = RegExpSource<R>,
40
41
  GroupCount extends number = CountCaptureGroups<S>,
41
42
  NamedGroups = RegExpNamedGroups<R>
42
43
  > = IsEmptyRecord<NamedGroups> extends true ? [
43
- match: string,
44
44
  ...captures: CaptureOptTuple<GroupCount>,
45
45
  offset: number,
46
46
  input: string,
47
47
  ] : [
48
- match: string,
49
48
  ...captures: CaptureOptTuple<GroupCount>,
50
49
  offset: number,
51
50
  input: string,
52
51
  groups: NamedGroups
53
52
  ];
54
53
  /**
55
- * string replacer is function or string
54
+ * Creates the parameter types for String.replace callback function.
55
+ *
56
+ * @example
57
+ * type Params = StringReplacerParams<typeof myRegex>;
58
+ * // [match: string, ...captures: string[], offset: number, string: string, groups?: {...}]
59
+ */
60
+ export type StringReplacerParams<
61
+ R extends RegExp,
62
+ S extends RegExpSource<R> = RegExpSource<R>,
63
+ GroupCount extends number = CountCaptureGroups<S>,
64
+ NamedGroups = RegExpNamedGroups<R>
65
+ > = [
66
+ /** The matched substring. */
67
+ matched: string,
68
+ /**
69
+ * The rest parameters of the replacer function, including captures, offset, input string, and optionally named groups.
70
+ */
71
+ ...StringReplacerRestArgs<R, S, GroupCount, NamedGroups>
72
+ ];
73
+ /**
74
+ * Represents the type of the replacer function used in `String.prototype.replace()`.
75
+ *
76
+ * This type is designed to provide precise type inference for the replacer function's parameters,
77
+ * including `match`, capture groups (both indexed and named), `offset`, `input`, and `groups`.
78
+ *
79
+ * @template R - The `RegExp` type for which the replacer function is being defined.
56
80
  */
57
- export type StringReplacerType<R> =
81
+ export type StringReplacerType<R extends RegExp> =
58
82
  R extends TypedRegExp<infer P extends string, infer F extends string>
59
- ? (...args: StringReplacerParams<TypedRegExp<P, F>, P>) => string
83
+ ? (...args: StringReplacerParams<R>) => string
60
84
  : R extends RegExp
61
- ? (match: string, ...rest: any[]) => string
85
+ ? (match: string, ...restArgs: any[]) => string
62
86
  : string;
63
87
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "literate-regex",
3
- "version": "0.6.2",
3
+ "version": "0.6.9",
4
4
  "description": "Write readable (literate) regex sources with # comments, then normalize them to JS RegExp.source at the type level.",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,