Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

logflare-transport-core

Package Overview
Dependencies
Maintainers
1
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

logflare-transport-core - npm Package Compare versions

Comparing version 0.2.4 to 0.2.5-1a27192b

.github/workflows/main.yml

12

dist/http_client.d.ts

@@ -1,6 +0,3 @@

/// <reference types="node" />
import { AxiosInstance } from "axios";
import stream from "stream";
interface IngestTransformsI {
jsNumbers: boolean;
numbersToFloats: boolean;
}

@@ -16,3 +13,2 @@ interface LogflareUserOptionsI {

declare class LogflareHttpClient {
protected axiosInstance: AxiosInstance;
protected readonly sourceToken: string;

@@ -23,10 +19,8 @@ protected readonly transforms?: IngestTransformsI;

protected readonly fromBrowser: boolean;
protected readonly apiBaseUrl: string;
constructor(options: LogflareUserOptionsI);
addLogEvent(logEvent: object | object[]): Promise<object>;
insertStream(): stream.Writable;
postLogEvents(batch: object[]): Promise<any>;
private _initializeResponseInterceptor;
private _handleResponse;
protected _handleError: (error: any) => Promise<never>;
addTypecasting(): Promise<void>;
}
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) {

@@ -38,26 +53,21 @@ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }

};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.LogflareHttpClient = void 0;
var axios_1 = __importDefault(require("axios"));
var lodash_1 = __importDefault(require("lodash"));
var typecasting_1 = require("./typecasting");
var stream_1 = __importDefault(require("stream"));
var defaultOptions = {
apiBaseUrl: "https://api.logflare.app",
};
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;

@@ -75,19 +85,9 @@ 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;
}
LogflareHttpClient.prototype.addLogEvent = function (logEvent) {
var _a;
return __awaiter(this, void 0, void 0, function () {
var logEvents;
return __generator(this, function (_b) {
return __generator(this, function (_a) {
logEvents = Array.isArray(logEvent) ? logEvent : [logEvent];
if ((_a = this === null || this === void 0 ? void 0 : this.transforms) === null || _a === void 0 ? void 0 : _a.jsNumbers) {
logEvents = lodash_1.default.map(logEvents, typecasting_1.applyNumberToStringTypecasting);
}
return [2 /*return*/, this.postLogEvents(logEvents)];

@@ -97,20 +97,5 @@ });

};
LogflareHttpClient.prototype.insertStream = function () {
var self = this;
var writeStream = new stream_1.default.Writable({
objectMode: true,
highWaterMark: 1,
});
writeStream._write = function (chunk, encoding, callback) {
self.addLogEvent(chunk)
.then(function () {
callback(null);
})
.catch(callback);
};
return writeStream;
};
LogflareHttpClient.prototype.postLogEvents = function (batch) {
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) {

@@ -120,28 +105,43 @@ 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);
}
payload = {
batch: batch
batch: batch,
};
_a.label = 1;
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*/];
}

@@ -151,2 +151,23 @@ });

};
LogflareHttpClient.prototype.addTypecasting = function () {
return __awaiter(this, void 0, void 0, function () {
var url;
return __generator(this, function (_a) {
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*/];
}
});
});
};
return LogflareHttpClient;

@@ -153,0 +174,0 @@ }());

{
"name": "logflare-transport-core",
"version": "0.2.4",
"version": "0.2.5-1a27192b",
"description": "A common core for Logflare javascript transports.",

@@ -12,8 +12,5 @@ "keywords": [

"dependencies": {
"@types/lodash": "^4.14.153",
"axios": "^0.19.2",
"big-integer": "^1.6.48",
"bignumber.js": "^9.0.0",
"decimal.js": "^10.2.0",
"lodash": "^4.17.15"
"decimal.js": "^10.2.0"
},

@@ -28,4 +25,4 @@ "devDependencies": {

"jest": "^26.0.1",
"moxios": "^0.4.0",
"prettier": "^2.0.5"
"prettier": "^2.0.5",
"typescript": "^4.5.4"
},

@@ -48,2 +45,2 @@ "scripts": {

}
}
}

@@ -1,11 +0,3 @@

import axios, { AxiosInstance, AxiosResponse } from "axios"
import _ from "lodash"
import {
applyNumberToStringTypecasting,
applyCustomTypecasting,
} from "./typecasting"
import stream from "stream"
interface IngestTransformsI {
jsNumbers: boolean
numbersToFloats: boolean
}

@@ -26,4 +18,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,5 +37,6 @@ protected readonly transforms?: IngestTransformsI

protected readonly fromBrowser: boolean
protected readonly apiBaseUrl: string
public constructor(options: LogflareUserOptionsI) {
const { sourceToken, apiKey, transforms, endpoint } = options
const {sourceToken, apiKey, transforms, endpoint} = options
if (!sourceToken || sourceToken == "") {

@@ -49,10 +53,3 @@ throw "Logflare API logging transport source token is NOT configured!"

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
}

@@ -62,49 +59,51 @@

let logEvents = Array.isArray(logEvent) ? logEvent : [logEvent]
if (this?.transforms?.jsNumbers) {
logEvents = _.map(logEvents, applyNumberToStringTypecasting)
}
return this.postLogEvents(logEvents)
}
public insertStream() {
const self = this
const writeStream = new stream.Writable({
objectMode: true,
highWaterMark: 1,
})
writeStream._write = function (chunk, encoding, callback) {
self.addLogEvent(chunk)
.then(() => {
callback(null)
})
.catch(callback)
}
return writeStream
}
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}`
}
const payload = {
batch
batch,
}
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

@@ -114,13 +113,15 @@ }

private _initializeResponseInterceptor = () => {
this.axiosInstance.interceptors.response.use(
this._handleResponse,
this._handleError
)
async addTypecasting() {
const url = new URL("/sources/", this.apiBaseUrl)
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 }
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,43 +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",
"X-API-KEY": "testApiKey",
})
expect(request.config.data).toBe(
JSON.stringify({batch: [le], source: testSourceToken})
)
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",
},
}
)
})

@@ -57,72 +61,23 @@

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
)}`
)
})
})
describe("LogflareHttpClient with options", () => {
let httpClient
let axiosInstance
beforeEach(() => {
httpClient = new LogflareHttpClient({
apiKey: "testApiKey",
sourceToken: "2222-2222",
apiBaseUrl: "http://non-existing.domain",
transforms: {jsNumbers: true},
})
const axiosInstance = httpClient.axiosInstance
moxios.install(axiosInstance)
})
afterEach(() => {
moxios.uninstall(axiosInstance)
})
it("trarnsforms js numbers if configured", async (done) => {
const le = {
message: "info log msg",
metadata: {number: 1, number2: 1.0},
}
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",
"X-API-KEY": "testApiKey",
})
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"}]}],"source":"2222-2222"}'
)
await request.respondWith({
status: 200,
response: apiResponseSuccess,
})
done()
})
const response = await httpClient.addLogEvent(le)
expect(response).toMatchObject(apiResponseSuccess)
})
})

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc