import type { Split, SplitPattern } from './split.ts'; import type { ForceDistributive } from './utils.ts'; export interface ParsedPattern { protocol: Token[] | undefined; hostname: Token[] | undefined; port: string | undefined; pathname: Token[] | undefined; search: string | undefined; } export type Parse = T extends ForceDistributive ? Split extends infer S extends SplitPattern ? { protocol: S['protocol'] extends string ? ParsePart : undefined; hostname: S['hostname'] extends string ? ParsePart : undefined; port: S['port'] extends string ? S['port'] : undefined; pathname: S['pathname'] extends string ? ParsePart : undefined; search: S['search'] extends string ? S['search'] : undefined; } : never : never; export type Variable = { type: 'variable'; name: string; }; export type Wildcard = { type: 'wildcard'; name?: string; }; export type Text = { type: 'text'; value: string; }; export type Separator = { type: 'separator'; }; export type Optional = { type: 'optional'; tokens: Token[]; }; export type Token = Variable | Wildcard | Text | Separator | Optional; type ParsePartState = { tokens: Token[]; optionals: Array; rest: string; }; type ParsePart = _ParsePart<{ tokens: []; optionals: []; rest: T; }, Sep>; type _ParsePart = S extends { rest: `${infer Head}${infer Tail}`; } ? Head extends Sep ? _ParsePart, Sep> : Head extends ':' ? IdentifierParse extends { identifier: infer name extends string; rest: infer rest extends string; } ? (name extends '' ? never : _ParsePart, Sep>) : never : Head extends '*' ? IdentifierParse extends { identifier: infer name extends string; rest: infer rest extends string; } ? _ParsePart, Sep> : never : Head extends '(' ? _ParsePart, Sep> : Head extends ')' ? PopOptional extends infer next extends ParsePartState ? _ParsePart : never : Head extends '\\' ? Tail extends `${infer L}${infer R}` ? _ParsePart, Sep> : never : _ParsePart, Sep> : S['optionals'] extends [] ? S['tokens'] : never; type AppendToken = S['optionals'] extends [...infer O extends Array, infer Top extends Token[]] ? { tokens: S['tokens']; optionals: [...O, [...Top, token]]; rest: rest; } : { tokens: [...S['tokens'], token]; optionals: S['optionals']; rest: rest; }; type AppendText = S['optionals'] extends [...infer O extends Array, infer Top extends Token[]] ? (Top extends [...infer Tokens extends Array, { type: 'text'; value: infer value extends string; }] ? { tokens: S['tokens']; optionals: [...O, [...Tokens, { type: 'text'; value: `${value}${text}`; }]]; rest: rest; } : { tokens: S['tokens']; optionals: [...O, [...Top, { type: 'text'; value: text; }]]; rest: rest; }) : (S['tokens'] extends [...infer Tokens extends Array, { type: 'text'; value: infer value extends string; }] ? { tokens: [...Tokens, { type: 'text'; value: `${value}${text}`; }]; optionals: S['optionals']; rest: rest; } : { tokens: [...S['tokens'], { type: 'text'; value: text; }]; optionals: S['optionals']; rest: rest; }); type PushOptional = { tokens: S['tokens']; optionals: [...S['optionals'], []]; rest: rest; }; type PopOptional = S['optionals'] extends [ ...infer O extends Array, infer Top extends Array ] ? O extends [...infer OO extends Array, infer Parent extends Token[]] ? { tokens: S['tokens']; optionals: [...OO, [...Parent, { type: 'optional'; tokens: Top; }]]; rest: R; } : { tokens: [...S['tokens'], { type: 'optional'; tokens: Top; }]; optionals: []; rest: R; } : never; type _a_z = 'a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i' | 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q' | 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z'; type _A_Z = Uppercase<_a_z>; type _0_9 = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'; type IdentifierHead = _a_z | _A_Z | '_' | '$'; type IdentifierTail = IdentifierHead | _0_9; type IdentifierParse = _IdentifierParse<{ identifier: ''; rest: T; }>; type _IdentifierParse = S extends { identifier: ''; rest: `${infer Head extends IdentifierHead}${infer Tail}`; } ? _IdentifierParse<{ identifier: Head; rest: Tail; }> : S extends { identifier: string; rest: `${infer Head extends IdentifierTail}${infer Tail}`; } ? _IdentifierParse<{ identifier: `${S['identifier']}${Head}`; rest: Tail; }> : S; export {}; //# sourceMappingURL=parse.d.ts.map