| 30 | import * as path from 'path'; |
| 31 | |
| 32 | class AxiosPlugin implements SwPlugin { |
| 33 | readonly module = 'axios'; |
| 34 | readonly versions = '*'; |
| 35 | |
| 36 | getVersion(installer: PluginInstaller): string { |
| 37 | // TODO: this method will not work in a bundle |
| 38 | try { |
| 39 | const indexPath = installer.resolve(this.module); |
| 40 | const dirname = indexPath.slice( |
| 41 | 0, |
| 42 | indexPath.lastIndexOf(`${path.sep}node_modules${path.sep}axios${path.sep}`) + 20, |
| 43 | ); |
| 44 | const packageJsonStr = fs.readFileSync(`${dirname}package.json`, { encoding: 'utf-8' }); |
| 45 | const pkg = JSON.parse(packageJsonStr); |
| 46 | return pkg.version; |
| 47 | } catch { |
| 48 | return ''; |
| 49 | } |
| 50 | } |
| 51 | |
| 52 | install(installer: PluginInstaller): void { |
| 53 | this.interceptClientRequest(installer); |
| 54 | } |
| 55 | |
| 56 | private interceptClientRequest(installer: PluginInstaller): void { |
| 57 | const axios = installer.require?.('axios') ?? require('axios'); |
| 58 | const Axios = axios.Axios; |
| 59 | const _request = Axios.prototype.request; |
| 60 | |
| 61 | Axios.prototype.request = axios.request = function (url?: any, config?: any) { |
| 62 | if (typeof url === 'string') config = config ? { ...config, url } : { url }; |
| 63 | else config = url ? { ...url } : {}; |
| 64 | |
| 65 | const { origin, host, pathname: operation } = new URL(config.url, config.baseURL ?? this.defaults?.baseURL); |
| 66 | const method = (config.method || 'GET').toUpperCase(); |
| 67 | const span = ignoreHttpMethodCheck(method) |
| 68 | ? DummySpan.create() |
| 69 | : ContextManager.current.newExitSpan(operation, Component.AXIOS, Component.HTTP); |
| 70 | |
| 71 | span.start(); |
| 72 | |
| 73 | try { |
| 74 | config.headers = config.headers ? { ...config.headers } : {}; |
| 75 | |
| 76 | span.component = Component.AXIOS; |
| 77 | span.layer = SpanLayer.HTTP; |
| 78 | span.peer = host; |
| 79 | |
| 80 | span.tag(Tag.httpURL(origin + operation)); |
| 81 | span.tag(Tag.httpMethod(method)); |
| 82 | |
| 83 | span.inject().items.forEach((item) => (config.headers[item.key] = item.value)); |
| 84 | |
| 85 | const copyStatus = (response: any) => { |
| 86 | if (response) { |
| 87 | if (response.status) { |
| 88 | span.tag(Tag.httpStatusCode(response.status)); |
| 89 |
nothing calls this directly
no outgoing calls
no test coverage detected