| 1389 | } |
| 1390 | |
| 1391 | char *cbm_pipeline_resolve_module(const cbm_pipeline_ctx_t *ctx, const char *source_rel, |
| 1392 | const char *module_path) { |
| 1393 | if (!ctx || !module_path) { |
| 1394 | return cbm_pipeline_fqn_module(ctx ? ctx->project_name : NULL, module_path); |
| 1395 | } |
| 1396 | |
| 1397 | /* 1. Try relative import resolution (existing logic) */ |
| 1398 | char *resolved = cbm_pipeline_resolve_relative_import(source_rel, module_path); |
| 1399 | if (resolved) { |
| 1400 | char *qn = cbm_pipeline_fqn_module(ctx->project_name, resolved); |
| 1401 | free(resolved); |
| 1402 | return qn; |
| 1403 | } |
| 1404 | |
| 1405 | /* 1b. Try build-tool path aliases (tsconfig/jsconfig paths today; |
| 1406 | * other loaders can register here later). Independent of pkgmap. */ |
| 1407 | if (ctx->path_aliases && source_rel) { |
| 1408 | const cbm_path_alias_map_t *amap = |
| 1409 | cbm_path_alias_find_for_file(ctx->path_aliases, source_rel); |
| 1410 | if (amap) { |
| 1411 | char *aliased = cbm_path_alias_resolve(amap, module_path); |
| 1412 | if (aliased) { |
| 1413 | char *qn = cbm_pipeline_fqn_module(ctx->project_name, aliased); |
| 1414 | free(aliased); |
| 1415 | return qn; |
| 1416 | } |
| 1417 | } |
| 1418 | } |
| 1419 | |
| 1420 | /* 2. No pkgmap → fall through immediately */ |
| 1421 | CBMHashTable *pkgmap = cbm_pipeline_get_pkgmap(); |
| 1422 | if (!pkgmap) { |
| 1423 | return cbm_pipeline_fqn_module(ctx->project_name, module_path); |
| 1424 | } |
| 1425 | |
| 1426 | /* 3. Exact lookup */ |
| 1427 | const char *mapped_qn = (const char *)cbm_ht_get(pkgmap, module_path); |
| 1428 | if (mapped_qn) { |
| 1429 | return strdup(mapped_qn); |
| 1430 | } |
| 1431 | |
| 1432 | /* 4. Prefix matching by separator type */ |
| 1433 | char *result = resolve_slash_prefix(pkgmap, module_path); |
| 1434 | if (!result) { |
| 1435 | result = resolve_dot_prefix(pkgmap, module_path, ctx->project_name); |
| 1436 | } |
| 1437 | if (!result) { |
| 1438 | result = resolve_backslash_prefix(pkgmap, module_path, ctx->project_name); |
| 1439 | } |
| 1440 | if (result) { |
| 1441 | return result; |
| 1442 | } |
| 1443 | |
| 1444 | /* 5. Fallthrough to default resolution */ |
| 1445 | return cbm_pipeline_fqn_module(ctx->project_name, module_path); |
| 1446 | } |
| 1447 | |
| 1448 | /* ── Import-target node resolver ─────────────────────────────────── */ |
no test coverage detected