logflare-transport-core
Advanced tools
Comparing version 0.2.5-5eb53706 to 0.2.5-84fdc5ab
/// <reference types="node" /> | ||
import { AxiosInstance } from "axios"; | ||
import stream from "stream"; | ||
@@ -16,3 +15,2 @@ interface IngestTransformsI { | ||
declare class LogflareHttpClient { | ||
protected axiosInstance: AxiosInstance; | ||
protected readonly sourceToken: string; | ||
@@ -23,2 +21,3 @@ protected readonly transforms?: IngestTransformsI; | ||
protected readonly fromBrowser: boolean; | ||
protected readonly apiBaseUrl: string; | ||
constructor(options: LogflareUserOptionsI); | ||
@@ -29,6 +28,3 @@ addLogEvent(logEvent: object | object[]): Promise<object>; | ||
addTypecasting(): Promise<void>; | ||
private _initializeResponseInterceptor; | ||
private _handleResponse; | ||
protected _handleError: (error: any) => Promise<never>; | ||
} | ||
export { LogflareHttpClient, LogflareUserOptionsI }; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
@@ -43,3 +58,2 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } | ||
exports.LogflareHttpClient = void 0; | ||
var axios_1 = __importDefault(require("axios")); | ||
var stream_1 = __importDefault(require("stream")); | ||
@@ -49,14 +63,16 @@ var defaultOptions = { | ||
}; | ||
var NetworkError = /** @class */ (function (_super) { | ||
__extends(NetworkError, _super); | ||
function NetworkError(message, response, data) { | ||
var _this = _super.call(this, message) || this; | ||
_this.response = response; | ||
_this.data = data; | ||
_this.name = "NetworkError"; | ||
return _this; | ||
} | ||
return NetworkError; | ||
}(Error)); | ||
var LogflareHttpClient = /** @class */ (function () { | ||
function LogflareHttpClient(options) { | ||
var _this = this; | ||
var _a; | ||
this._initializeResponseInterceptor = function () { | ||
_this.axiosInstance.interceptors.response.use(_this._handleResponse, _this._handleError); | ||
}; | ||
this._handleResponse = function (_a) { | ||
var data = _a.data; | ||
return data; | ||
}; | ||
this._handleError = function (error) { return Promise.reject(error); }; | ||
var sourceToken = options.sourceToken, apiKey = options.apiKey, transforms = options.transforms, endpoint = options.endpoint; | ||
@@ -74,9 +90,3 @@ if (!sourceToken || sourceToken == "") { | ||
this.apiKey = apiKey; | ||
this.axiosInstance = axios_1.default.create({ | ||
baseURL: options.apiBaseUrl || defaultOptions.apiBaseUrl, | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
}); | ||
this._initializeResponseInterceptor(); | ||
this.apiBaseUrl = options.apiBaseUrl || defaultOptions.apiBaseUrl; | ||
} | ||
@@ -109,3 +119,3 @@ LogflareHttpClient.prototype.addLogEvent = function (logEvent) { | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url, payload, e_1; | ||
var path, payload, url, response, data, e_1; | ||
return __generator(this, function (_a) { | ||
@@ -115,6 +125,6 @@ switch (_a.label) { | ||
if (this.endpoint === "typecasting") { | ||
url = "/logs/typecasts?api_key=" + this.apiKey + "&source=" + this.sourceToken; | ||
path = "/logs/typecasts?api_key=".concat(this.apiKey, "&source=").concat(this.sourceToken); | ||
} | ||
else { | ||
url = "/logs?api_key=" + this.apiKey + "&source=" + this.sourceToken; | ||
path = "/logs?api_key=".concat(this.apiKey, "&source=").concat(this.sourceToken); | ||
} | ||
@@ -126,18 +136,33 @@ payload = { | ||
case 1: | ||
_a.trys.push([1, 3, , 4]); | ||
return [4 /*yield*/, this.axiosInstance.post(url, payload)]; | ||
case 2: return [2 /*return*/, _a.sent()]; | ||
_a.trys.push([1, 4, , 5]); | ||
url = new URL(path, this.apiBaseUrl); | ||
return [4 /*yield*/, fetch(url.toString(), { | ||
body: JSON.stringify(payload), | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}, | ||
})]; | ||
case 2: | ||
response = _a.sent(); | ||
return [4 /*yield*/, response.json()]; | ||
case 3: | ||
data = _a.sent(); | ||
if (!response.ok) { | ||
throw new NetworkError("Network response was not ok for \"".concat(url, "\""), response, data); | ||
} | ||
return [2 /*return*/, data]; | ||
case 4: | ||
e_1 = _a.sent(); | ||
if (e_1.response) { | ||
console.error("Logflare API request failed with " + e_1.response.status + " status: " + JSON.stringify(e_1.response.data)); | ||
if (e_1) { | ||
if (e_1 instanceof NetworkError && e_1.response) { | ||
console.error("Logflare API request failed with ".concat(e_1.response.status, " status: ").concat(JSON.stringify(e_1.data))); | ||
} | ||
else if (e_1 instanceof Error) { | ||
console.error(e_1.message); | ||
} | ||
} | ||
else if (e_1.request) { | ||
console.error("Logflare API request failed: " + e_1.request); | ||
} | ||
else { | ||
console.error(e_1.message); | ||
} | ||
return [2 /*return*/, e_1]; | ||
case 4: return [2 /*return*/]; | ||
case 5: return [2 /*return*/]; | ||
} | ||
@@ -149,5 +174,18 @@ }); | ||
return __awaiter(this, void 0, void 0, function () { | ||
var url; | ||
return __generator(this, function (_a) { | ||
this.axiosInstance.post("/sources/"); | ||
return [2 /*return*/]; | ||
switch (_a.label) { | ||
case 0: | ||
url = new URL("/sources/", this.apiBaseUrl); | ||
return [4 /*yield*/, fetch(url.toString(), { | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}, | ||
})]; | ||
case 1: | ||
_a.sent(); | ||
return [2 /*return*/]; | ||
} | ||
}); | ||
@@ -154,0 +192,0 @@ }); |
@@ -13,8 +13,10 @@ "use strict"; | ||
}; | ||
var __spreadArrays = (this && this.__spreadArrays) || function () { | ||
for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; | ||
for (var r = Array(s), k = 0, i = 0; i < il; i++) | ||
for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) | ||
r[k] = a[j]; | ||
return r; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { | ||
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { | ||
if (ar || !(i in from)) { | ||
if (!ar) ar = Array.prototype.slice.call(from, 0, i); | ||
ar[i] = from[i]; | ||
} | ||
} | ||
return to.concat(ar || Array.prototype.slice.call(from)); | ||
}; | ||
@@ -67,3 +69,3 @@ var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return { | ||
path: __spreadArrays(["metadata"], filteredKeys), | ||
path: __spreadArray(["metadata"], filteredKeys, true), | ||
from: from, | ||
@@ -70,0 +72,0 @@ to: to, |
{ | ||
"name": "logflare-transport-core", | ||
"version": "0.2.5-5eb53706", | ||
"version": "0.2.5-84fdc5ab", | ||
"description": "A common core for Logflare javascript transports.", | ||
@@ -13,3 +13,2 @@ "keywords": [ | ||
"@types/lodash": "^4.14.153", | ||
"axios": "^0.21.1", | ||
"big-integer": "^1.6.48", | ||
@@ -28,4 +27,4 @@ "bignumber.js": "^9.0.0", | ||
"jest": "^26.0.1", | ||
"moxios": "^0.4.0", | ||
"prettier": "^2.0.5" | ||
"prettier": "^2.0.5", | ||
"typescript": "^4.5.4" | ||
}, | ||
@@ -32,0 +31,0 @@ "scripts": { |
@@ -1,7 +0,1 @@ | ||
import axios, {AxiosInstance, AxiosResponse} from "axios" | ||
import _ from "lodash" | ||
import { | ||
applyNumberToStringTypecasting, | ||
applyCustomTypecasting, | ||
} from "./typecasting" | ||
import stream from "stream" | ||
@@ -26,4 +20,15 @@ | ||
class NetworkError extends Error { | ||
name = "NetworkError" | ||
constructor( | ||
message: string, | ||
public response: Response, | ||
public data: unknown | ||
) { | ||
super(message) | ||
} | ||
} | ||
class LogflareHttpClient { | ||
protected axiosInstance: AxiosInstance | ||
protected readonly sourceToken: string | ||
@@ -34,2 +39,3 @@ protected readonly transforms?: IngestTransformsI | ||
protected readonly fromBrowser: boolean | ||
protected readonly apiBaseUrl: string | ||
@@ -49,10 +55,3 @@ public constructor(options: LogflareUserOptionsI) { | ||
this.apiKey = apiKey | ||
this.axiosInstance = axios.create({ | ||
baseURL: options.apiBaseUrl || defaultOptions.apiBaseUrl, | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
}) | ||
this._initializeResponseInterceptor() | ||
this.apiBaseUrl = options.apiBaseUrl || defaultOptions.apiBaseUrl | ||
} | ||
@@ -82,7 +81,7 @@ | ||
async postLogEvents(batch: object[]) { | ||
let url | ||
let path | ||
if (this.endpoint === "typecasting") { | ||
url = `/logs/typecasts?api_key=${this.apiKey}&source=${this.sourceToken}` | ||
path = `/logs/typecasts?api_key=${this.apiKey}&source=${this.sourceToken}` | ||
} else { | ||
url = `/logs?api_key=${this.apiKey}&source=${this.sourceToken}` | ||
path = `/logs?api_key=${this.apiKey}&source=${this.sourceToken}` | ||
} | ||
@@ -93,16 +92,37 @@ const payload = { | ||
try { | ||
return await this.axiosInstance.post(url, payload) | ||
} catch (e) { | ||
if (e.response) { | ||
console.error( | ||
`Logflare API request failed with ${ | ||
e.response.status | ||
} status: ${JSON.stringify(e.response.data)}` | ||
const url = new URL(path, this.apiBaseUrl) | ||
const response = await fetch(url.toString(), { | ||
body: JSON.stringify(payload), | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}, | ||
}) | ||
const data = await response.json() | ||
if (!response.ok) { | ||
throw new NetworkError( | ||
`Network response was not ok for "${url}"`, | ||
response, | ||
data | ||
) | ||
} else if (e.request) { | ||
console.error(`Logflare API request failed: ${e.request}`) | ||
} else { | ||
console.error(e.message) | ||
} | ||
return data | ||
} catch (e) { | ||
if (e) { | ||
if (e instanceof NetworkError && e.response) { | ||
console.error( | ||
`Logflare API request failed with ${ | ||
e.response.status | ||
} status: ${JSON.stringify(e.data)}` | ||
) | ||
} else if (e instanceof Error) { | ||
console.error(e.message) | ||
} | ||
} | ||
return e | ||
@@ -113,16 +133,14 @@ } | ||
async addTypecasting() { | ||
this.axiosInstance.post("/sources/") | ||
} | ||
const url = new URL("/sources/", this.apiBaseUrl) | ||
private _initializeResponseInterceptor = () => { | ||
this.axiosInstance.interceptors.response.use( | ||
this._handleResponse, | ||
this._handleError | ||
) | ||
await fetch(url.toString(), { | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}, | ||
}) | ||
} | ||
private _handleResponse = ({data}: AxiosResponse) => data | ||
protected _handleError = (error: any) => Promise.reject(error) | ||
} | ||
export {LogflareHttpClient, LogflareUserOptionsI} |
@@ -1,5 +0,4 @@ | ||
import moxios from "moxios" | ||
import {LogflareHttpClient} from "./main" | ||
const testApiKey = "testApiKey" | ||
const testBaseUrl = "http://non-existing.domain" | ||
@@ -11,42 +10,48 @@ const testSourceToken = "2222-2222" | ||
let httpClient | ||
let axiosInstance | ||
let nativeFetch | ||
beforeAll(() => { | ||
nativeFetch = global.fetch | ||
}) | ||
beforeEach(() => { | ||
httpClient = new LogflareHttpClient({ | ||
apiKey: "testApiKey", | ||
sourceToken: "2222-2222", | ||
apiKey: testApiKey, | ||
sourceToken: testSourceToken, | ||
apiBaseUrl: "http://non-existing.domain", | ||
}) | ||
const axiosInstance = httpClient.axiosInstance | ||
moxios.install(axiosInstance) | ||
}) | ||
afterEach(() => { | ||
moxios.uninstall(axiosInstance) | ||
global.fetch.mockClear() | ||
}) | ||
it("successfully send a post request", async (done) => { | ||
const le = {message: "info log msg", metadata: {p1: "v1"}} | ||
afterAll(() => { | ||
global.fetch = nativeFetch | ||
}) | ||
moxios.wait(async () => { | ||
let request = moxios.requests.mostRecent() | ||
expect(request.config.baseURL).toBe(testBaseUrl) | ||
expect(request.headers).toMatchObject({ | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}) | ||
expect(request.config.data).toBe( | ||
JSON.stringify({batch: [le]}) | ||
) | ||
await request.respondWith({ | ||
it("successfully send a post request", async () => { | ||
global.fetch = jest.fn(() => | ||
Promise.resolve({ | ||
json: () => Promise.resolve(apiResponseSuccess), | ||
ok: true, | ||
status: 200, | ||
response: apiResponseSuccess, | ||
}) | ||
done() | ||
}) | ||
) | ||
const le = {message: "info log msg", metadata: {p1: "v1"}} | ||
const response = await httpClient.addLogEvent(le) | ||
expect(response).toMatchObject(apiResponseSuccess) | ||
expect(global.fetch).toHaveBeenCalledWith( | ||
`${testBaseUrl}/logs?api_key=${testApiKey}&source=${testSourceToken}`, | ||
{ | ||
body: JSON.stringify({batch: [le]}), | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
) | ||
}) | ||
@@ -56,20 +61,21 @@ | ||
const storeLog = (inputs) => (consoleLogData += inputs) | ||
it("prints to console on error", async (done) => { | ||
it("prints to console on error", async () => { | ||
const errorResponse = {message: "Schema validation error"} | ||
console["error"] = jest.fn(storeLog) | ||
global.fetch = jest.fn(() => | ||
Promise.resolve({ | ||
json: () => Promise.resolve(errorResponse), | ||
ok: false, | ||
status: 406, | ||
}) | ||
) | ||
const le = {message: "info log msg", metadata: {p1: "v1"}} | ||
moxios.wait(async () => { | ||
let request = moxios.requests.mostRecent() | ||
await request.respondWith({ | ||
status: 406, | ||
response: {message: "Schema validation error"}, | ||
}) | ||
done() | ||
}) | ||
await httpClient.addLogEvent(le) | ||
expect(consoleLogData).toBe( | ||
'Logflare API request failed with 406 status: {"message":"Schema validation error"}' | ||
`Logflare API request failed with 406 status: ${JSON.stringify( | ||
errorResponse | ||
)}` | ||
) | ||
@@ -81,19 +87,26 @@ }) | ||
let httpClient | ||
let axiosInstance | ||
let nativeFetch | ||
beforeAll(() => { | ||
nativeFetch = global.fetch | ||
}) | ||
beforeEach(() => { | ||
httpClient = new LogflareHttpClient({ | ||
apiKey: "testApiKey", | ||
sourceToken: "2222-2222", | ||
apiBaseUrl: "http://non-existing.domain", | ||
apiKey: testApiKey, | ||
sourceToken: testSourceToken, | ||
apiBaseUrl: testBaseUrl, | ||
transforms: {jsNumbers: true}, | ||
}) | ||
const axiosInstance = httpClient.axiosInstance | ||
moxios.install(axiosInstance) | ||
}) | ||
afterEach(() => { | ||
moxios.uninstall(axiosInstance) | ||
global.fetch.mockClear() | ||
}) | ||
it.skip("transforms js numbers if configured", async (done) => { | ||
afterAll(() => { | ||
global.fetch = nativeFetch | ||
}) | ||
it.skip("transforms js numbers if configured", async () => { | ||
const le = { | ||
@@ -104,25 +117,42 @@ message: "info log msg", | ||
moxios.wait(async () => { | ||
let request = moxios.requests.mostRecent() | ||
expect(request.config.baseURL).toBe(testBaseUrl) | ||
expect(request.headers).toMatchObject({ | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}) | ||
expect(request.config.data).toBe( | ||
'{"batch":[{"body":{"message":"info log msg","metadata":{"number":"1","number2":"1"}},"typecasts":[{"path":["metadata","number"],"from":"string","to":"float"},{"path":["metadata","number2"],"from":"string","to":"float"}]}]}' | ||
) | ||
await request.respondWith({ | ||
global.fetch = jest.fn(() => | ||
Promise.resolve({ | ||
json: () => Promise.resolve(apiResponseSuccess), | ||
ok: true, | ||
status: 200, | ||
response: apiResponseSuccess, | ||
}) | ||
done() | ||
}) | ||
) | ||
const response = await httpClient.addLogEvent(le) | ||
expect(response).toMatchObject(apiResponseSuccess) | ||
expect(global.fetch).toHaveBeenCalledWith( | ||
`${testBaseUrl}/logs?api_key=${testApiKey}&source=${testSourceToken}`, | ||
{ | ||
body: JSON.stringify({ | ||
batch: [ | ||
{ | ||
body: le, | ||
typecasts: [ | ||
{ | ||
path: ["metadata", "number"], | ||
from: "string", | ||
to: "float", | ||
}, | ||
{ | ||
path: ["metadata", "number2"], | ||
from: "string", | ||
to: "float", | ||
}, | ||
], | ||
}, | ||
], | ||
}), | ||
method: "POST", | ||
headers: { | ||
Accept: "application/json, text/plain, */*", | ||
"Content-Type": "application/json", | ||
}, | ||
} | ||
) | ||
}) | ||
}) |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
49519
5
1134
2
- Removedaxios@^0.21.1
- Removedaxios@0.21.4(transitive)
- Removedfollow-redirects@1.15.9(transitive)