| 1115 | } |
| 1116 | |
| 1117 | char *cbm_pipeline_resolve_module(const cbm_pipeline_ctx_t *ctx, const char *source_rel, |
| 1118 | const char *module_path) { |
| 1119 | if (!ctx || !module_path) { |
| 1120 | return cbm_pipeline_fqn_module(ctx ? ctx->project_name : NULL, module_path); |
| 1121 | } |
| 1122 | |
| 1123 | /* 1. Try relative import resolution (existing logic) */ |
| 1124 | char *resolved = cbm_pipeline_resolve_relative_import(source_rel, module_path); |
| 1125 | if (resolved) { |
| 1126 | char *qn = cbm_pipeline_fqn_module(ctx->project_name, resolved); |
| 1127 | free(resolved); |
| 1128 | return qn; |
| 1129 | } |
| 1130 | |
| 1131 | /* 1b. Try build-tool path aliases (tsconfig/jsconfig paths today; |
| 1132 | * other loaders can register here later). Independent of pkgmap. */ |
| 1133 | if (ctx->path_aliases && source_rel) { |
| 1134 | const cbm_path_alias_map_t *amap = |
| 1135 | cbm_path_alias_find_for_file(ctx->path_aliases, source_rel); |
| 1136 | if (amap) { |
| 1137 | char *aliased = cbm_path_alias_resolve(amap, module_path); |
| 1138 | if (aliased) { |
| 1139 | char *qn = cbm_pipeline_fqn_module(ctx->project_name, aliased); |
| 1140 | free(aliased); |
| 1141 | return qn; |
| 1142 | } |
| 1143 | } |
| 1144 | } |
| 1145 | |
| 1146 | /* 2. No pkgmap → fall through immediately */ |
| 1147 | CBMHashTable *pkgmap = cbm_pipeline_get_pkgmap(); |
| 1148 | if (!pkgmap) { |
| 1149 | return cbm_pipeline_fqn_module(ctx->project_name, module_path); |
| 1150 | } |
| 1151 | |
| 1152 | /* 3. Exact lookup */ |
| 1153 | const char *mapped_qn = (const char *)cbm_ht_get(pkgmap, module_path); |
| 1154 | if (mapped_qn) { |
| 1155 | return strdup(mapped_qn); |
| 1156 | } |
| 1157 | |
| 1158 | /* 4. Prefix matching by separator type */ |
| 1159 | char *result = resolve_slash_prefix(pkgmap, module_path); |
| 1160 | if (!result) { |
| 1161 | result = resolve_dot_prefix(pkgmap, module_path, ctx->project_name); |
| 1162 | } |
| 1163 | if (!result) { |
| 1164 | result = resolve_backslash_prefix(pkgmap, module_path, ctx->project_name); |
| 1165 | } |
| 1166 | if (result) { |
| 1167 | return result; |
| 1168 | } |
| 1169 | |
| 1170 | /* 5. Fallthrough to default resolution */ |
| 1171 | return cbm_pipeline_fqn_module(ctx->project_name, module_path); |
| 1172 | } |
| 1173 | |
| 1174 | /* ── Import-target node resolver ─────────────────────────────────── */ |
no test coverage detected