| 249 | } |
| 250 | |
| 251 | export async function parseImportGlob( |
| 252 | code: string, |
| 253 | importer: string | undefined, |
| 254 | root: string, |
| 255 | resolveId: IdResolver, |
| 256 | logger?: Logger, |
| 257 | ): Promise<ParsedImportGlob[]> { |
| 258 | let cleanCode: string |
| 259 | try { |
| 260 | cleanCode = stripLiteral(code) |
| 261 | } catch { |
| 262 | // skip invalid js code |
| 263 | return [] |
| 264 | } |
| 265 | const matches = Array.from(cleanCode.matchAll(importGlobRE)) |
| 266 | |
| 267 | const tasks = matches.map(async (match, index) => { |
| 268 | const start = match.index! |
| 269 | |
| 270 | const err = (msg: string) => { |
| 271 | const e = new Error(`Invalid glob import syntax: ${msg}`) |
| 272 | ;(e as any).pos = start |
| 273 | return e |
| 274 | } |
| 275 | |
| 276 | const end = |
| 277 | findCorrespondingCloseParenthesisPosition( |
| 278 | cleanCode, |
| 279 | start + match[0].length, |
| 280 | ) + 1 |
| 281 | if (end <= 0) { |
| 282 | throw err('Close parenthesis not found') |
| 283 | } |
| 284 | |
| 285 | const statementCode = code.slice(start, end) |
| 286 | |
| 287 | const rootAst = (await parseAstAsync(statementCode)).body[0] |
| 288 | if (rootAst.type !== 'ExpressionStatement') { |
| 289 | throw err(`Expect CallExpression, got ${rootAst.type}`) |
| 290 | } |
| 291 | const ast = rootAst.expression |
| 292 | if (ast.type !== 'CallExpression') { |
| 293 | throw err(`Expect CallExpression, got ${ast.type}`) |
| 294 | } |
| 295 | if (ast.arguments.length < 1 || ast.arguments.length > 2) |
| 296 | throw err(`Expected 1-2 arguments, but got ${ast.arguments.length}`) |
| 297 | |
| 298 | const arg1 = ast.arguments[0] |
| 299 | const arg2 = ast.arguments[1] |
| 300 | |
| 301 | const globs: string[] = [] |
| 302 | |
| 303 | const validateLiteral = ( |
| 304 | element: ESTree.Expression | ESTree.SpreadElement | null, |
| 305 | ) => { |
| 306 | if (!element) return |
| 307 | if (element.type === 'Literal') { |
| 308 | if (typeof element.value !== 'string') |