Emit TRPC_CALLS edge. Extract procedure path from callee chain. */
| 1940 | |
| 1941 | /* Emit TRPC_CALLS edge. Extract procedure path from callee chain. */ |
| 1942 | static void emit_trpc_edge(cbm_gbuf_t *gbuf, const cbm_gbuf_node_t *source, const CBMCall *call, |
| 1943 | const cbm_resolution_t *res) { |
| 1944 | /* tRPC calls: trpc.user.getById.query() → extract "user.getById" */ |
| 1945 | const char *callee = call->callee_name; |
| 1946 | if (!callee) { |
| 1947 | return; |
| 1948 | } |
| 1949 | /* Strip trailing .query/.mutate/.subscribe */ |
| 1950 | char proc[CBM_SZ_256]; |
| 1951 | snprintf(proc, sizeof(proc), "%s", callee); |
| 1952 | char *last_dot = strrchr(proc, '.'); |
| 1953 | if (last_dot && (strcmp(last_dot, ".query") == 0 || strcmp(last_dot, ".mutate") == 0 || |
| 1954 | strcmp(last_dot, ".subscribe") == 0 || strcmp(last_dot, ".useQuery") == 0 || |
| 1955 | strcmp(last_dot, ".useMutation") == 0)) { |
| 1956 | *last_dot = '\0'; |
| 1957 | } |
| 1958 | /* Strip leading trpc. */ |
| 1959 | const char *p = proc; |
| 1960 | if (strncmp(p, "trpc.", CBM_SZ_5) == 0) { |
| 1961 | p += CBM_SZ_5; |
| 1962 | } |
| 1963 | |
| 1964 | char route_qn[CBM_SZ_512]; |
| 1965 | snprintf(route_qn, sizeof(route_qn), "__trpc__%s", p); |
| 1966 | |
| 1967 | int64_t route_id = |
| 1968 | cbm_gbuf_upsert_node(gbuf, "Route", p, route_qn, "", 0, 0, "{\"source\":\"trpc\"}"); |
| 1969 | |
| 1970 | char esc_c[CBM_SZ_256]; |
| 1971 | cbm_json_escape(esc_c, sizeof(esc_c), call->callee_name); |
| 1972 | char props[CBM_SZ_1K]; |
| 1973 | snprintf(props, sizeof(props), "{\"callee\":\"%s\",\"procedure\":\"%s\",\"confidence\":%.2f}", |
| 1974 | esc_c, p, res->confidence); |
| 1975 | cbm_gbuf_insert_edge(gbuf, source->id, route_id, "TRPC_CALLS", props); |
| 1976 | } |
| 1977 | |
| 1978 | /* When suppress_plain_calls is true (a TS/JS/TSX weak short-name member-call |
| 1979 | * match, #592/#606), every service classification below still runs — only the |
no test coverage detected