(
args: string[],
options: { preferTrailingValue?: boolean } = {},
)
| 96 | } |
| 97 | |
| 98 | export function splitSelectorFromArgs( |
| 99 | args: string[], |
| 100 | options: { preferTrailingValue?: boolean } = {}, |
| 101 | ): { selectorExpression: string; rest: string[] } | null { |
| 102 | if (args.length === 0) return null; |
| 103 | const preferTrailingValue = options.preferTrailingValue ?? false; |
| 104 | let i = 0; |
| 105 | const boundaries: number[] = []; |
| 106 | while (i < args.length) { |
| 107 | const token = args[i]; |
| 108 | if (token === undefined || !isSelectorToken(token)) break; |
| 109 | i += 1; |
| 110 | const candidate = args.slice(0, i).join(' ').trim(); |
| 111 | if (!candidate) continue; |
| 112 | if (tryParseSelectorChain(candidate)) { |
| 113 | boundaries.push(i); |
| 114 | } |
| 115 | } |
| 116 | if (boundaries.length === 0) return null; |
| 117 | const lastBoundary = boundaries.at(-1); |
| 118 | if (lastBoundary === undefined) return null; |
| 119 | let boundary = lastBoundary; |
| 120 | if (preferTrailingValue) { |
| 121 | for (let i = boundaries.length - 1; i >= 0; i -= 1) { |
| 122 | const candidateBoundary = boundaries[i]; |
| 123 | if (candidateBoundary === undefined) continue; |
| 124 | if (candidateBoundary < args.length) { |
| 125 | boundary = candidateBoundary; |
| 126 | break; |
| 127 | } |
| 128 | } |
| 129 | } |
| 130 | const selectorExpression = args.slice(0, boundary).join(' ').trim(); |
| 131 | if (!selectorExpression) return null; |
| 132 | return { |
| 133 | selectorExpression, |
| 134 | rest: args.slice(boundary), |
| 135 | }; |
| 136 | } |
| 137 | |
| 138 | function parseSelector(segment: string): Selector { |
| 139 | const raw = segment.trim(); |
no test coverage detected