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

react-icecream-charts

Package Overview
Dependencies
Maintainers
3
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-icecream-charts - npm Package Compare versions

Comparing version 0.10.1 to 0.10.2

esm/_chart/utils/hooks.d.ts

2

esm/_chart/chart.d.ts

@@ -40,2 +40,2 @@ /**

}
export declare function createHighOptions(type: ChartType, chartOptions: ChartOptions | undefined, langData: LangData, plotOptions?: PlotOptions, specifiedChartHighOptions?: Highcharts.Options): Highcharts.Options;
export declare function createHighOptions(type: ChartType, chartOptions: ChartOptions | undefined, langData: LangData, plotOptions?: PlotOptions, specifiedChartHighOptions?: Highcharts.Options, events?: Highcharts.ChartEventsOptions): Highcharts.Options;

@@ -21,3 +21,3 @@ import Highcharts from 'highcharts';

// 特定图表类型的内部配置
specifiedChartHighOptions) {
specifiedChartHighOptions, events) {
if (chartOptions === void 0) { chartOptions = {}; }

@@ -32,2 +32,27 @@ // 通用的默认配置

}
},
// https://github.com/highcharts/highcharts/issues/6538
// highcharts bug 更新 options 里的 event handle 不会生效,导致调用触发的是第一次注册的 handle
// 这里一开始注册一个 handle,通过调用外部函数的方式实现类似更新 handle 的机制
events: {
load: function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (events === null || events === void 0 ? void 0 : events.load) {
(_a = events.load.bind(this)) === null || _a === void 0 ? void 0 : _a.apply(void 0, args);
}
},
redraw: function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (events === null || events === void 0 ? void 0 : events.redraw) {
(_a = events.redraw.bind(this)) === null || _a === void 0 ? void 0 : _a.apply(void 0, args);
}
}
}

@@ -34,0 +59,0 @@ },

@@ -13,1 +13,2 @@ import { Ref } from 'react';

export declare function useHighOptions(chartOptions: Highcharts.Options, { chartRef: outerChartRef, isMap, loading, langData, callback }: Options): readonly [import("react").RefObject<HTMLDivElement>, import("react").MutableRefObject<() => void>];
export declare function useChartEventsOptions(events?: Pick<Highcharts.ChartEventsOptions, 'redraw' | 'load'>): Highcharts.ChartEventsOptions;

@@ -5,2 +5,3 @@ import { useEffect, useImperativeHandle, useLayoutEffect, useRef } from 'react';

import memoize from 'lodash.memoize';
import { useUnstableEvent } from './utils/hooks';
var loadHighstock = memoize(function (langOptions) { return import('highcharts/highstock').then(function (Highstock) {

@@ -91,1 +92,23 @@ NoDataToDisplay(Highstock);

}
// 支持 selection event 的时候需要考虑来自用户传入的回调
export function useChartEventsOptions(events) {
if (events === void 0) { events = {}; }
var redraw = useUnstableEvent(function (chart, event) {
if (events.redraw) {
events.redraw.bind(chart)(event);
}
});
var load = useUnstableEvent(function (chart, event) {
if (events.load) {
events.load.bind(chart)(event);
}
});
return {
redraw: function (event) {
redraw(this, event);
},
load: function (event) {
load(this, event);
}
};
}

@@ -23,5 +23,5 @@ var __assign = (this && this.__assign) || function () {

};
import React, { useRef, useMemo, useCallback } from 'react';
import React, { useRef, useMemo } from 'react';
import { createPieOptions } from './options';
import { useHighOptions } from '../_chart';
import { useChartEventsOptions, useHighOptions } from '../_chart';
import { cssObjectToLiterialString } from '../_chart/utils/style';

@@ -36,23 +36,29 @@ import { useConfig } from '../config-provider';

var langData = useConfig().langData;
var handleRedraw = useCallback(function (chart) {
var _a, _b, _c;
// legend 只能相对于整个图表居中, 调整 legend 位置,让 legend 相对 series 居中
var legend = chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend;
if (legend === false || (legend === null || legend === void 0 ? void 0 : legend.align) === undefined || (legend === null || legend === void 0 ? void 0 : legend.align) === 'right-center') {
if (((_a = chart.options.legend) === null || _a === void 0 ? void 0 : _a.y) !== chart.plotTop / 2) {
var updatedLegendOptions = { y: chart.plotTop / 2 };
chart.legend.update(updatedLegendOptions);
var events = useChartEventsOptions({
load: wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend),
redraw: function () {
var _a, _b, _c;
// eslint-disable-next-line @typescript-eslint/no-this-alias
var chart = this;
// legend 只能相对于整个图表居中, 调整 legend 位置,让 legend 相对 series 居中
var legend = chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend;
if (legend === false || (legend === null || legend === void 0 ? void 0 : legend.align) === undefined || (legend === null || legend === void 0 ? void 0 : legend.align) === 'right-center') {
if (((_a = chart.options.legend) === null || _a === void 0 ? void 0 : _a.y) !== chart.plotTop / 2) {
var updatedLegendOptions = { y: chart.plotTop / 2 };
chart.legend.update(updatedLegendOptions);
}
}
// 设置内部 title
if (innerTitle) {
(_b = innerTitleRef.current) === null || _b === void 0 ? void 0 : _b.destroy();
innerTitleRef.current = createInnerTitle(chart, innerTitle, !!innerSubtitle);
}
if (innerSubtitle) {
(_c = innerSubtitleRef.current) === null || _c === void 0 ? void 0 : _c.destroy();
innerSubtitleRef.current = createInnerSubtitle(chart, innerSubtitle, !!innerTitle);
}
return wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend);
}
// 设置内部 title
if (innerTitle) {
(_b = innerTitleRef.current) === null || _b === void 0 ? void 0 : _b.destroy();
innerTitleRef.current = createInnerTitle(chart, innerTitle, !!innerSubtitle);
}
if (innerSubtitle) {
(_c = innerSubtitleRef.current) === null || _c === void 0 ? void 0 : _c.destroy();
innerSubtitleRef.current = createInnerSubtitle(chart, innerSubtitle, !!innerTitle);
}
}, [chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend, innerSubtitle, innerTitle]);
var pieOptions = useMemo(function () { return createPieOptions(langData, plotOptions, chartOptions, series, handleRedraw); }, [langData, plotOptions, chartOptions, series, handleRedraw]);
});
var pieOptions = useMemo(function () { return createPieOptions(langData, plotOptions, chartOptions, series, events); }, [langData, plotOptions, chartOptions, series, events]);
var ref = useHighOptions(pieOptions, {

@@ -110,1 +116,42 @@ chartRef: chartRef,

}
// 参考1:https://stackoverflow.com/a/51534428
// 参考2:https://github.com/highcharts/highcharts/blob/ee7de2bd881e820ee8ab534e3373b68283d54f93/ts/Core/Legend/Legend.ts#L1097
// 当图表加载完成时,获取图例的最大宽度和图例之间的间隔,根据要生成的列数计算图例所需要的宽度 widthA,
// 再获取图例在画布上能用的最大宽度 widthB,如果 widthA 小于等于 widthB,把图例的总宽度设为 widthA,
// 如果 widthA 大于 widthB,单列展示,图例的总宽度等于图例的最大宽度
function wrapRender(legendOptions) {
if (legendOptions == null)
return;
if (legendOptions === false)
return;
var columns = legendOptions.columns;
if (columns != null && columns <= 1)
return;
function renderElements() {
// highcharts 8.x 的 ts 声明存在大量类型缺失,升级 highcharts 到最新版本即可解决
var legend = this.legend;
if (legend) {
legend.destroy();
}
// distance between 2 elements
var itemDistance = legend.options.itemDistance || 0;
// the biggest element
var maxItemWidth = legend.maxItemWidth;
// make the width of the legend in the size of 2 largest elements +
// distance
var nextLegendWidth = (maxItemWidth + itemDistance) * columns - itemDistance;
// Compute how wide the legend is allowed to be
var allowedWidth = legend.chart.spacingBox.width - 2 * legend.padding - legend.options.x;
// if the length of the 2 largest elements + the distance between them
// is less than the width of container, we make 1 row, else
// set legend width 2 max elements + distance between
if (allowedWidth < nextLegendWidth) {
legend.options.width = maxItemWidth;
}
else {
legend.options.width = nextLegendWidth;
}
this.render();
}
return renderElements;
}

@@ -86,2 +86,2 @@ import Highcharts, { CSSObject } from 'highcharts';

}
export declare function createPieOptions(langData: LangData, options?: PlotPieOptions, chartOptions?: ChartPieOptions, series?: SeriesPieOptions[], onRedraw?: (chart: Highcharts.Chart) => void): Highcharts.Options;
export declare function createPieOptions(langData: LangData, options?: PlotPieOptions, chartOptions?: ChartPieOptions, series?: SeriesPieOptions[], events?: Highcharts.ChartEventsOptions): Highcharts.Options;

@@ -27,3 +27,3 @@ var __assign = (this && this.__assign) || function () {

import { createHighOptions, createHighLegendOptions, createHighSeriesOptions, isPointOptionsObject, createHighPointOptions } from '../_chart';
export function createPieOptions(langData, options, chartOptions, series, onRedraw) {
export function createPieOptions(langData, options, chartOptions, series, events) {
var pieOptions = {

@@ -62,15 +62,5 @@ colors: [

},
series: createSeriesPieOptions(series),
chart: {
// TODO 方法之间的合并会有问题,这里可能挪到 callback 里面去更好
events: {
load: wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend),
redraw: function () {
onRedraw === null || onRedraw === void 0 ? void 0 : onRedraw(this);
return wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend);
}
}
}
series: createSeriesPieOptions(series)
};
return createHighOptions('pie', omit(chartOptions, 'legend'), langData, options, pieOptions);
return createHighOptions('pie', omit(chartOptions, 'legend'), langData, options, pieOptions, events);
}

@@ -119,42 +109,1 @@ function createPieLegendOptions(options) {

}
// 参考1:https://stackoverflow.com/a/51534428
// 参考2:https://github.com/highcharts/highcharts/blob/ee7de2bd881e820ee8ab534e3373b68283d54f93/ts/Core/Legend/Legend.ts#L1097
// 当图表加载完成时,获取图例的最大宽度和图例之间的间隔,根据要生成的列数计算图例所需要的宽度 widthA,
// 再获取图例在画布上能用的最大宽度 widthB,如果 widthA 小于等于 widthB,把图例的总宽度设为 widthA,
// 如果 widthA 大于 widthB,单列展示,图例的总宽度等于图例的最大宽度
function wrapRender(legendOptions) {
if (legendOptions == null)
return;
if (legendOptions === false)
return;
var columns = legendOptions.columns;
if (columns != null && columns <= 1)
return;
function renderElements() {
// highcharts 8.x 的 ts 声明存在大量类型缺失,升级 highcharts 到最新版本即可解决
var legend = this.legend;
if (legend) {
legend.destroy();
}
// distance between 2 elements
var itemDistance = legend.options.itemDistance || 0;
// the biggest element
var maxItemWidth = legend.maxItemWidth;
// make the width of the legend in the size of 2 largest elements +
// distance
var nextLegendWidth = (maxItemWidth + itemDistance) * columns - itemDistance;
// Compute how wide the legend is allowed to be
var allowedWidth = legend.chart.spacingBox.width - 2 * legend.padding - legend.options.x;
// if the length of the 2 largest elements + the distance between them
// is less than the width of container, we make 1 row, else
// set legend width 2 max elements + distance between
if (allowedWidth < nextLegendWidth) {
legend.options.width = maxItemWidth;
}
else {
legend.options.width = nextLegendWidth;
}
this.render();
}
return renderElements;
}

@@ -40,2 +40,2 @@ /**

}
export declare function createHighOptions(type: ChartType, chartOptions: ChartOptions | undefined, langData: LangData, plotOptions?: PlotOptions, specifiedChartHighOptions?: Highcharts.Options): Highcharts.Options;
export declare function createHighOptions(type: ChartType, chartOptions: ChartOptions | undefined, langData: LangData, plotOptions?: PlotOptions, specifiedChartHighOptions?: Highcharts.Options, events?: Highcharts.ChartEventsOptions): Highcharts.Options;

@@ -37,3 +37,3 @@ "use strict";

// 特定图表类型的内部配置
specifiedChartHighOptions) {
specifiedChartHighOptions, events) {
if (chartOptions === void 0) { chartOptions = {}; }

@@ -48,2 +48,27 @@ // 通用的默认配置

}
},
// https://github.com/highcharts/highcharts/issues/6538
// highcharts bug 更新 options 里的 event handle 不会生效,导致调用触发的是第一次注册的 handle
// 这里一开始注册一个 handle,通过调用外部函数的方式实现类似更新 handle 的机制
events: {
load: function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (events === null || events === void 0 ? void 0 : events.load) {
(_a = events.load.bind(this)) === null || _a === void 0 ? void 0 : _a.apply(void 0, args);
}
},
redraw: function () {
var _a;
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
if (events === null || events === void 0 ? void 0 : events.redraw) {
(_a = events.redraw.bind(this)) === null || _a === void 0 ? void 0 : _a.apply(void 0, args);
}
}
}

@@ -50,0 +75,0 @@ },

@@ -13,1 +13,2 @@ import { Ref } from 'react';

export declare function useHighOptions(chartOptions: Highcharts.Options, { chartRef: outerChartRef, isMap, loading, langData, callback }: Options): readonly [import("react").RefObject<HTMLDivElement>, import("react").MutableRefObject<() => void>];
export declare function useChartEventsOptions(events?: Pick<Highcharts.ChartEventsOptions, 'redraw' | 'load'>): Highcharts.ChartEventsOptions;

@@ -25,3 +25,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.useHighOptions = void 0;
exports.useChartEventsOptions = exports.useHighOptions = void 0;
var react_1 = require("react");

@@ -31,2 +31,3 @@ var highcharts_1 = __importDefault(require("highcharts"));

var lodash_memoize_1 = __importDefault(require("lodash.memoize"));
var hooks_1 = require("./utils/hooks");
var loadHighstock = lodash_memoize_1.default(function (langOptions) { return Promise.resolve().then(function () { return __importStar(require('highcharts/highstock')); }).then(function (Highstock) {

@@ -118,1 +119,24 @@ no_data_to_display_1.default(Highstock);

}
// 支持 selection event 的时候需要考虑来自用户传入的回调
function useChartEventsOptions(events) {
if (events === void 0) { events = {}; }
var redraw = hooks_1.useUnstableEvent(function (chart, event) {
if (events.redraw) {
events.redraw.bind(chart)(event);
}
});
var load = hooks_1.useUnstableEvent(function (chart, event) {
if (events.load) {
events.load.bind(chart)(event);
}
});
return {
redraw: function (event) {
redraw(this, event);
},
load: function (event) {
load(this, event);
}
};
}
exports.useChartEventsOptions = useChartEventsOptions;

@@ -60,23 +60,29 @@ "use strict";

var langData = config_provider_1.useConfig().langData;
var handleRedraw = react_1.useCallback(function (chart) {
var _a, _b, _c;
// legend 只能相对于整个图表居中, 调整 legend 位置,让 legend 相对 series 居中
var legend = chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend;
if (legend === false || (legend === null || legend === void 0 ? void 0 : legend.align) === undefined || (legend === null || legend === void 0 ? void 0 : legend.align) === 'right-center') {
if (((_a = chart.options.legend) === null || _a === void 0 ? void 0 : _a.y) !== chart.plotTop / 2) {
var updatedLegendOptions = { y: chart.plotTop / 2 };
chart.legend.update(updatedLegendOptions);
var events = _chart_1.useChartEventsOptions({
load: wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend),
redraw: function () {
var _a, _b, _c;
// eslint-disable-next-line @typescript-eslint/no-this-alias
var chart = this;
// legend 只能相对于整个图表居中, 调整 legend 位置,让 legend 相对 series 居中
var legend = chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend;
if (legend === false || (legend === null || legend === void 0 ? void 0 : legend.align) === undefined || (legend === null || legend === void 0 ? void 0 : legend.align) === 'right-center') {
if (((_a = chart.options.legend) === null || _a === void 0 ? void 0 : _a.y) !== chart.plotTop / 2) {
var updatedLegendOptions = { y: chart.plotTop / 2 };
chart.legend.update(updatedLegendOptions);
}
}
// 设置内部 title
if (innerTitle) {
(_b = innerTitleRef.current) === null || _b === void 0 ? void 0 : _b.destroy();
innerTitleRef.current = createInnerTitle(chart, innerTitle, !!innerSubtitle);
}
if (innerSubtitle) {
(_c = innerSubtitleRef.current) === null || _c === void 0 ? void 0 : _c.destroy();
innerSubtitleRef.current = createInnerSubtitle(chart, innerSubtitle, !!innerTitle);
}
return wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend);
}
// 设置内部 title
if (innerTitle) {
(_b = innerTitleRef.current) === null || _b === void 0 ? void 0 : _b.destroy();
innerTitleRef.current = createInnerTitle(chart, innerTitle, !!innerSubtitle);
}
if (innerSubtitle) {
(_c = innerSubtitleRef.current) === null || _c === void 0 ? void 0 : _c.destroy();
innerSubtitleRef.current = createInnerSubtitle(chart, innerSubtitle, !!innerTitle);
}
}, [chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend, innerSubtitle, innerTitle]);
var pieOptions = react_1.useMemo(function () { return options_1.createPieOptions(langData, plotOptions, chartOptions, series, handleRedraw); }, [langData, plotOptions, chartOptions, series, handleRedraw]);
});
var pieOptions = react_1.useMemo(function () { return options_1.createPieOptions(langData, plotOptions, chartOptions, series, events); }, [langData, plotOptions, chartOptions, series, events]);
var ref = _chart_1.useHighOptions(pieOptions, {

@@ -135,1 +141,42 @@ chartRef: chartRef,

}
// 参考1:https://stackoverflow.com/a/51534428
// 参考2:https://github.com/highcharts/highcharts/blob/ee7de2bd881e820ee8ab534e3373b68283d54f93/ts/Core/Legend/Legend.ts#L1097
// 当图表加载完成时,获取图例的最大宽度和图例之间的间隔,根据要生成的列数计算图例所需要的宽度 widthA,
// 再获取图例在画布上能用的最大宽度 widthB,如果 widthA 小于等于 widthB,把图例的总宽度设为 widthA,
// 如果 widthA 大于 widthB,单列展示,图例的总宽度等于图例的最大宽度
function wrapRender(legendOptions) {
if (legendOptions == null)
return;
if (legendOptions === false)
return;
var columns = legendOptions.columns;
if (columns != null && columns <= 1)
return;
function renderElements() {
// highcharts 8.x 的 ts 声明存在大量类型缺失,升级 highcharts 到最新版本即可解决
var legend = this.legend;
if (legend) {
legend.destroy();
}
// distance between 2 elements
var itemDistance = legend.options.itemDistance || 0;
// the biggest element
var maxItemWidth = legend.maxItemWidth;
// make the width of the legend in the size of 2 largest elements +
// distance
var nextLegendWidth = (maxItemWidth + itemDistance) * columns - itemDistance;
// Compute how wide the legend is allowed to be
var allowedWidth = legend.chart.spacingBox.width - 2 * legend.padding - legend.options.x;
// if the length of the 2 largest elements + the distance between them
// is less than the width of container, we make 1 row, else
// set legend width 2 max elements + distance between
if (allowedWidth < nextLegendWidth) {
legend.options.width = maxItemWidth;
}
else {
legend.options.width = nextLegendWidth;
}
this.render();
}
return renderElements;
}

@@ -86,2 +86,2 @@ import Highcharts, { CSSObject } from 'highcharts';

}
export declare function createPieOptions(langData: LangData, options?: PlotPieOptions, chartOptions?: ChartPieOptions, series?: SeriesPieOptions[], onRedraw?: (chart: Highcharts.Chart) => void): Highcharts.Options;
export declare function createPieOptions(langData: LangData, options?: PlotPieOptions, chartOptions?: ChartPieOptions, series?: SeriesPieOptions[], events?: Highcharts.ChartEventsOptions): Highcharts.Options;

@@ -33,3 +33,3 @@ "use strict";

var _chart_1 = require("../_chart");
function createPieOptions(langData, options, chartOptions, series, onRedraw) {
function createPieOptions(langData, options, chartOptions, series, events) {
var pieOptions = {

@@ -68,15 +68,5 @@ colors: [

},
series: createSeriesPieOptions(series),
chart: {
// TODO 方法之间的合并会有问题,这里可能挪到 callback 里面去更好
events: {
load: wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend),
redraw: function () {
onRedraw === null || onRedraw === void 0 ? void 0 : onRedraw(this);
return wrapRender(chartOptions === null || chartOptions === void 0 ? void 0 : chartOptions.legend);
}
}
}
series: createSeriesPieOptions(series)
};
return _chart_1.createHighOptions('pie', omit_1.default(chartOptions, 'legend'), langData, options, pieOptions);
return _chart_1.createHighOptions('pie', omit_1.default(chartOptions, 'legend'), langData, options, pieOptions, events);
}

@@ -126,42 +116,1 @@ exports.createPieOptions = createPieOptions;

}
// 参考1:https://stackoverflow.com/a/51534428
// 参考2:https://github.com/highcharts/highcharts/blob/ee7de2bd881e820ee8ab534e3373b68283d54f93/ts/Core/Legend/Legend.ts#L1097
// 当图表加载完成时,获取图例的最大宽度和图例之间的间隔,根据要生成的列数计算图例所需要的宽度 widthA,
// 再获取图例在画布上能用的最大宽度 widthB,如果 widthA 小于等于 widthB,把图例的总宽度设为 widthA,
// 如果 widthA 大于 widthB,单列展示,图例的总宽度等于图例的最大宽度
function wrapRender(legendOptions) {
if (legendOptions == null)
return;
if (legendOptions === false)
return;
var columns = legendOptions.columns;
if (columns != null && columns <= 1)
return;
function renderElements() {
// highcharts 8.x 的 ts 声明存在大量类型缺失,升级 highcharts 到最新版本即可解决
var legend = this.legend;
if (legend) {
legend.destroy();
}
// distance between 2 elements
var itemDistance = legend.options.itemDistance || 0;
// the biggest element
var maxItemWidth = legend.maxItemWidth;
// make the width of the legend in the size of 2 largest elements +
// distance
var nextLegendWidth = (maxItemWidth + itemDistance) * columns - itemDistance;
// Compute how wide the legend is allowed to be
var allowedWidth = legend.chart.spacingBox.width - 2 * legend.padding - legend.options.x;
// if the length of the 2 largest elements + the distance between them
// is less than the width of container, we make 1 row, else
// set legend width 2 max elements + distance between
if (allowedWidth < nextLegendWidth) {
legend.options.width = maxItemWidth;
}
else {
legend.options.width = nextLegendWidth;
}
this.render();
}
return renderElements;
}
{
"name": "react-icecream-charts",
"version": "0.10.1",
"version": "0.10.2",
"license": "MIT",

@@ -5,0 +5,0 @@ "main": "esm/index.js",

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