|
1 | 1 | import { exactly } from './inputs'
|
| 2 | +import type { GetValue } from './types/escape' |
| 3 | +import type { InputSource } from './types/sources' |
2 | 4 |
|
3 |
| -export interface Input<T extends string = never> { |
| 5 | +export interface Input<V extends string, G extends string = never> { |
4 | 6 | /** this adds a new pattern to the current input */
|
5 |
| - and: <X extends string = never>(input: string | Input<X>) => Input<T | X> |
| 7 | + and: <I extends InputSource<string, G>, Groups extends string = never>( |
| 8 | + input: I |
| 9 | + ) => Input<`${V}${GetValue<I>}`, G | Groups> |
6 | 10 | /** this provides an alternative to the current input */
|
7 |
| - or: <X extends string = never>(input: string | Input<X>) => Input<T | X> |
| 11 | + or: <I extends InputSource<string, G>, Groups extends string = never>( |
| 12 | + input: I |
| 13 | + ) => Input<`(${V}|${GetValue<I>})`, G | Groups> |
8 | 14 | /** this is a positive lookbehind. Make sure to check [browser support](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#browser_compatibility) as not all browsers support lookbehinds (notably Safari) */
|
9 |
| - after: (input: string | Input) => Input<T> |
| 15 | + after: <I extends InputSource<string>>(input: I) => Input<`(?<=${GetValue<I>})${V}`, G> |
10 | 16 | /** this is a positive lookahead */
|
11 |
| - before: (input: string | Input) => Input<T> |
| 17 | + before: <I extends InputSource<string>>(input: I) => Input<`${V}(?=${GetValue<I>})`, G> |
12 | 18 | /** these is a negative lookbehind. Make sure to check [browser support](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#browser_compatibility) as not all browsers support lookbehinds (notably Safari) */
|
13 |
| - notAfter: (input: string | Input) => Input<T> |
| 19 | + notAfter: <I extends InputSource<string>>(input: I) => Input<`(?<!${GetValue<I>})${V}`, G> |
14 | 20 | /** this is a negative lookahead */
|
15 |
| - notBefore: (input: string | Input) => Input<T> |
| 21 | + notBefore: <I extends InputSource<string>>(input: I) => Input<`${V}(?!${GetValue<I>})`, G> |
16 | 22 | times: {
|
17 | 23 | /** repeat the previous pattern an exact number of times */
|
18 |
| - (number: number): Input<T> |
19 |
| - /** specify a range of times to repeat the previous pattern */ |
20 |
| - between: (min: number, max: number) => Input<T> |
| 24 | + <N extends number>(number: N): Input<`(${V}){${N}}`, G> |
21 | 25 | /** specify that the expression can repeat any number of times, _including none_ */
|
22 |
| - any: () => Input<T> |
| 26 | + any: () => Input<`(${V})*`, G> |
| 27 | + /** specify a range of times to repeat the previous pattern */ |
| 28 | + between: <Min extends number, Max extends number>( |
| 29 | + min: Min, |
| 30 | + max: Max |
| 31 | + ) => Input<`(${V}){${Min},${Max}}`, G> |
23 | 32 | /** specify that the expression must occur at least x times */
|
24 |
| - atLeast: (min: number) => Input<T> |
| 33 | + atLeast: <N extends number>(number: N) => Input<`(${V}){${N},}`, G> |
25 | 34 | }
|
26 | 35 | /** this defines the entire input so far as a named capture group. You will get type safety when using the resulting RegExp with `String.match()` */
|
27 |
| - as: <K extends string>(key: K) => Input<T | K> |
| 36 | + as: <K extends string>(key: K) => Input<`(?<${K}>${V})`, G | K> |
28 | 37 | /** this allows you to match beginning/ends of lines with `at.lineStart()` and `at.lineEnd()` */
|
29 | 38 | at: {
|
30 |
| - lineStart: () => Input<T> |
31 |
| - lineEnd: () => Input<T> |
| 39 | + lineStart: () => Input<`^${V}`, G> |
| 40 | + lineEnd: () => Input<`${V}$`, G> |
32 | 41 | }
|
33 | 42 | /** this allows you to mark the input so far as optional */
|
34 |
| - optionally: () => Input<T> |
| 43 | + optionally: () => Input<`(${V})?`, G> |
35 | 44 | toString: () => string
|
36 | 45 | }
|
37 | 46 |
|
38 |
| -export const createInput = <T extends string = never>(s: string | Input<T>): Input<T> => { |
| 47 | +export const createInput = <Value extends string, Groups extends string = never>( |
| 48 | + s: Value | Input<Groups, Value> |
| 49 | +): Input<Value, Groups> => { |
39 | 50 | return {
|
40 | 51 | toString: () => s.toString(),
|
41 | 52 | and: input => createInput(`${s}${exactly(input)}`),
|
|
0 commit comments