Socket
Socket
Sign inDemoInstall

@grpc/grpc-js

Package Overview
Dependencies
Maintainers
3
Versions
174
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@grpc/grpc-js - npm Package Compare versions

Comparing version 1.9.14 to 1.9.15

1

build/src/compression-filter.d.ts

@@ -15,2 +15,3 @@ /// <reference types="node" />

private currentCompressionAlgorithm;
private maxReceiveMessageLength;
constructor(channelOptions: ChannelOptions, sharedFilterConfig: SharedCompressionFilterConfig);

@@ -17,0 +18,0 @@ sendMetadata(metadata: Promise<Metadata>): Promise<Metadata>;

69

build/src/compression-filter.js

@@ -76,2 +76,6 @@ "use strict";

class DeflateHandler extends CompressionHandler {
constructor(maxRecvMessageLength) {
super();
this.maxRecvMessageLength = maxRecvMessageLength;
}
compressMessage(message) {

@@ -91,10 +95,21 @@ return new Promise((resolve, reject) => {

return new Promise((resolve, reject) => {
zlib.inflate(message, (err, output) => {
if (err) {
reject(err);
let totalLength = 0;
const messageParts = [];
const decompresser = zlib.createInflate();
decompresser.on('data', (chunk) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
decompresser.destroy();
reject({
code: constants_1.Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
});
}
else {
resolve(output);
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(message);
decompresser.end();
});

@@ -104,2 +119,6 @@ }

class GzipHandler extends CompressionHandler {
constructor(maxRecvMessageLength) {
super();
this.maxRecvMessageLength = maxRecvMessageLength;
}
compressMessage(message) {

@@ -119,10 +138,21 @@ return new Promise((resolve, reject) => {

return new Promise((resolve, reject) => {
zlib.unzip(message, (err, output) => {
if (err) {
reject(err);
let totalLength = 0;
const messageParts = [];
const decompresser = zlib.createGunzip();
decompresser.on('data', (chunk) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
decompresser.destroy();
reject({
code: constants_1.Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
});
}
else {
resolve(output);
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(message);
decompresser.end();
});

@@ -144,3 +174,3 @@ }

}
function getCompressionHandler(compressionName) {
function getCompressionHandler(compressionName, maxReceiveMessageSize) {
switch (compressionName) {

@@ -150,5 +180,5 @@ case 'identity':

case 'deflate':
return new DeflateHandler();
return new DeflateHandler(maxReceiveMessageSize);
case 'gzip':
return new GzipHandler();
return new GzipHandler(maxReceiveMessageSize);
default:

@@ -160,3 +190,3 @@ return new UnknownHandler(compressionName);

constructor(channelOptions, sharedFilterConfig) {
var _a;
var _a, _b;
super();

@@ -168,6 +198,7 @@ this.sharedFilterConfig = sharedFilterConfig;

const compressionAlgorithmKey = channelOptions['grpc.default_compression_algorithm'];
this.maxReceiveMessageLength = (_a = channelOptions['grpc.max_receive_message_length']) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH;
if (compressionAlgorithmKey !== undefined) {
if (isCompressionAlgorithmKey(compressionAlgorithmKey)) {
const clientSelectedEncoding = compression_algorithms_1.CompressionAlgorithms[compressionAlgorithmKey];
const serverSupportedEncodings = (_a = sharedFilterConfig.serverSupportedEncodingHeader) === null || _a === void 0 ? void 0 : _a.split(',');
const serverSupportedEncodings = (_b = sharedFilterConfig.serverSupportedEncodingHeader) === null || _b === void 0 ? void 0 : _b.split(',');
/**

@@ -183,3 +214,3 @@ * There are two possible situations here:

this.currentCompressionAlgorithm = clientSelectedEncoding;
this.sendCompression = getCompressionHandler(this.currentCompressionAlgorithm);
this.sendCompression = getCompressionHandler(this.currentCompressionAlgorithm, -1);
}

@@ -210,3 +241,3 @@ }

if (typeof encoding === 'string') {
this.receiveCompression = getCompressionHandler(encoding);
this.receiveCompression = getCompressionHandler(encoding, this.maxReceiveMessageLength);
}

@@ -213,0 +244,0 @@ }

@@ -0,1 +1,2 @@

/// <reference types="node" />
import { ClientDuplexStream, ClientReadableStream, ClientUnaryCall, ClientWritableStream, ServiceError } from './call';

@@ -2,0 +3,0 @@ import { CallCredentials, OAuth2Client } from './call-credentials';

@@ -29,3 +29,2 @@ "use strict";

const logging_1 = require("./logging");
const max_message_size_filter_1 = require("./max-message-size-filter");
const http_proxy_1 = require("./http_proxy");

@@ -238,3 +237,2 @@ const uri_parser_1 = require("./uri-parser");

this.filterStackFactory = new filter_stack_1.FilterStackFactory([
new max_message_size_filter_1.MaxMessageSizeFilterFactory(this.options),
new compression_filter_1.CompressionFilterFactory(this, this.options),

@@ -241,0 +239,0 @@ ]);

@@ -0,1 +1,2 @@

/// <reference types="node" />
import { LogVerbosity } from './constants';

@@ -2,0 +3,0 @@ export declare const getLogger: () => Partial<Console>;

@@ -24,3 +24,2 @@ "use strict";

const zlib = require("zlib");
const util_1 = require("util");
const constants_1 = require("./constants");

@@ -32,4 +31,2 @@ const metadata_1 = require("./metadata");

const TRACER_NAME = 'server_call';
const unzip = (0, util_1.promisify)(zlib.unzip);
const inflate = (0, util_1.promisify)(zlib.inflate);
function trace(text) {

@@ -286,15 +283,41 @@ logging.trace(constants_1.LogVerbosity.DEBUG, TRACER_NAME, text);

getDecompressedMessage(message, encoding) {
if (encoding === 'deflate') {
return inflate(message.subarray(5));
const messageContents = message.subarray(5);
if (encoding === 'identity') {
return messageContents;
}
else if (encoding === 'gzip') {
return unzip(message.subarray(5));
else if (encoding === 'deflate' || encoding === 'gzip') {
let decompresser;
if (encoding === 'deflate') {
decompresser = zlib.createInflate();
}
else {
decompresser = zlib.createGunzip();
}
return new Promise((resolve, reject) => {
let totalLength = 0;
const messageParts = [];
decompresser.on('data', (chunk) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxReceiveMessageSize !== -1 && totalLength > this.maxReceiveMessageSize) {
decompresser.destroy();
reject({
code: constants_1.Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxReceiveMessageSize}`
});
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(messageContents);
decompresser.end();
});
}
else if (encoding === 'identity') {
return message.subarray(5);
else {
return Promise.reject({
code: constants_1.Status.UNIMPLEMENTED,
details: `Received message compressed with unsupported encoding "${encoding}"`,
});
}
return Promise.reject({
code: constants_1.Status.UNIMPLEMENTED,
details: `Received message compressed with unsupported encoding "${encoding}"`,
});
}

@@ -532,3 +555,3 @@ sendMetadata(customMetadata) {

setupReadable(readable, encoding) {
const decoder = new stream_decoder_1.StreamDecoder();
const decoder = new stream_decoder_1.StreamDecoder(this.maxReceiveMessageSize);
let readsDone = false;

@@ -544,18 +567,27 @@ let pendingMessageProcessing = false;

this.stream.on('data', async (data) => {
const messages = decoder.write(data);
let messages;
try {
messages = decoder.write(data);
}
catch (e) {
this.sendError({
code: constants_1.Status.RESOURCE_EXHAUSTED,
details: e.message
});
return;
}
pendingMessageProcessing = true;
this.stream.pause();
for (const message of messages) {
if (this.maxReceiveMessageSize !== -1 &&
message.length > this.maxReceiveMessageSize) {
this.sendError({
code: constants_1.Status.RESOURCE_EXHAUSTED,
details: `Received message larger than max (${message.length} vs. ${this.maxReceiveMessageSize})`,
});
return;
}
this.emit('receiveMessage');
const compressed = message.readUInt8(0) === 1;
const compressedMessageEncoding = compressed ? encoding : 'identity';
const decompressedMessage = await this.getDecompressedMessage(message, compressedMessageEncoding);
let decompressedMessage;
try {
decompressedMessage = await this.getDecompressedMessage(message, compressedMessageEncoding);
}
catch (e) {
this.sendError(e);
return;
}
// Encountered an error with decompression; it'll already have been propogated back

@@ -562,0 +594,0 @@ // Just return early

/// <reference types="node" />
export declare class StreamDecoder {
private maxReadMessageLength;
private readState;

@@ -10,3 +11,4 @@ private readCompressFlag;

private readMessageRemaining;
constructor(maxReadMessageLength: number);
write(data: Buffer): Buffer[];
}

@@ -27,3 +27,4 @@ "use strict";

class StreamDecoder {
constructor() {
constructor(maxReadMessageLength) {
this.maxReadMessageLength = maxReadMessageLength;
this.readState = ReadState.NO_DATA;

@@ -61,2 +62,5 @@ this.readCompressFlag = Buffer.alloc(1);

this.readMessageSize = this.readPartialSize.readUInt32BE(0);
if (this.maxReadMessageLength !== -1 && this.readMessageSize > this.maxReadMessageLength) {
throw new Error(`Received message larger than max (${this.readMessageSize} vs ${this.maxReadMessageLength})`);
}
this.readMessageRemaining = this.readMessageSize;

@@ -63,0 +67,0 @@ if (this.readMessageRemaining > 0) {

@@ -44,2 +44,3 @@ "use strict";

constructor(http2Stream, callEventTracker, listener, transport, callId) {
var _a;
this.http2Stream = http2Stream;

@@ -50,3 +51,2 @@ this.callEventTracker = callEventTracker;

this.callId = callId;
this.decoder = new stream_decoder_1.StreamDecoder();
this.isReadFilterPending = false;

@@ -67,2 +67,4 @@ this.isPushPending = false;

this.internalError = null;
const maxReceiveMessageLength = (_a = transport.getOptions()['grpc.max_receive_message_length']) !== null && _a !== void 0 ? _a : constants_1.DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH;
this.decoder = new stream_decoder_1.StreamDecoder(maxReceiveMessageLength);
http2Stream.on('response', (headers, flags) => {

@@ -126,3 +128,10 @@ let headersString = '';

this.trace('receive HTTP/2 data frame of length ' + data.length);
const messages = this.decoder.write(data);
let messages;
try {
messages = this.decoder.write(data);
}
catch (e) {
this.cancelWithStatus(constants_1.Status.RESOURCE_EXHAUSTED, e.message);
return;
}
for (const message of messages) {

@@ -129,0 +138,0 @@ this.trace('parsed message of length ' + message.length);

@@ -23,2 +23,3 @@ /// <reference types="node" />

getPeerName(): string;
getOptions(): ChannelOptions;
createCall(metadata: Metadata, host: string, method: string, listener: SubchannelCallInterceptingListener, subchannelCallStatsTracker: Partial<CallEventTracker>): SubchannelCall;

@@ -30,2 +31,3 @@ addDisconnectListener(listener: TransportDisconnectListener): void;

private session;
private options;
/**

@@ -117,2 +119,3 @@ * Name of the remote server, if it is not the same as the subchannel

getPeerName(): string;
getOptions(): ChannelOptions;
shutdown(): void;

@@ -119,0 +122,0 @@ }

@@ -46,2 +46,3 @@ "use strict";

this.session = session;
this.options = options;
this.remoteName = remoteName;

@@ -463,2 +464,5 @@ /**

}
getOptions() {
return this.options;
}
shutdown() {

@@ -465,0 +469,0 @@ this.session.close();

{
"name": "@grpc/grpc-js",
"version": "1.9.14",
"version": "1.9.15",
"description": "gRPC Library for Node - pure JS implementation",

@@ -5,0 +5,0 @@ "homepage": "https://grpc.io/",

@@ -24,3 +24,3 @@ /*

import { CompressionAlgorithms } from './compression-algorithms';
import { LogVerbosity } from './constants';
import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, LogVerbosity, Status } from './constants';
import { BaseFilter, Filter, FilterFactory } from './filter';

@@ -102,2 +102,6 @@ import * as logging from './logging';

class DeflateHandler extends CompressionHandler {
constructor(private maxRecvMessageLength: number) {
super();
}
compressMessage(message: Buffer) {

@@ -117,9 +121,21 @@ return new Promise<Buffer>((resolve, reject) => {

return new Promise<Buffer>((resolve, reject) => {
zlib.inflate(message, (err, output) => {
if (err) {
reject(err);
} else {
resolve(output);
let totalLength = 0;
const messageParts: Buffer[] = [];
const decompresser = zlib.createInflate();
decompresser.on('data', (chunk: Buffer) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
decompresser.destroy();
reject({
code: Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
});
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(message);
decompresser.end();
});

@@ -130,2 +146,6 @@ }

class GzipHandler extends CompressionHandler {
constructor(private maxRecvMessageLength: number) {
super();
}
compressMessage(message: Buffer) {

@@ -145,9 +165,21 @@ return new Promise<Buffer>((resolve, reject) => {

return new Promise<Buffer>((resolve, reject) => {
zlib.unzip(message, (err, output) => {
if (err) {
reject(err);
} else {
resolve(output);
let totalLength = 0;
const messageParts: Buffer[] = [];
const decompresser = zlib.createGunzip();
decompresser.on('data', (chunk: Buffer) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxRecvMessageLength !== -1 && totalLength > this.maxRecvMessageLength) {
decompresser.destroy();
reject({
code: Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxRecvMessageLength}`
});
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(message);
decompresser.end();
});

@@ -177,3 +209,3 @@ }

function getCompressionHandler(compressionName: string): CompressionHandler {
function getCompressionHandler(compressionName: string, maxReceiveMessageSize: number): CompressionHandler {
switch (compressionName) {

@@ -183,5 +215,5 @@ case 'identity':

case 'deflate':
return new DeflateHandler();
return new DeflateHandler(maxReceiveMessageSize);
case 'gzip':
return new GzipHandler();
return new GzipHandler(maxReceiveMessageSize);
default:

@@ -196,2 +228,3 @@ return new UnknownHandler(compressionName);

private currentCompressionAlgorithm: CompressionAlgorithm = 'identity';
private maxReceiveMessageLength: number;

@@ -206,2 +239,3 @@ constructor(

channelOptions['grpc.default_compression_algorithm'];
this.maxReceiveMessageLength = channelOptions['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH
if (compressionAlgorithmKey !== undefined) {

@@ -227,3 +261,4 @@ if (isCompressionAlgorithmKey(compressionAlgorithmKey)) {

this.sendCompression = getCompressionHandler(
this.currentCompressionAlgorithm
this.currentCompressionAlgorithm,
-1
);

@@ -260,3 +295,3 @@ }

if (typeof encoding === 'string') {
this.receiveCompression = getCompressionHandler(encoding);
this.receiveCompression = getCompressionHandler(encoding, this.maxReceiveMessageLength);
}

@@ -263,0 +298,0 @@ }

@@ -36,3 +36,2 @@ /*

import { SubchannelAddress } from './subchannel-address';
import { MaxMessageSizeFilterFactory } from './max-message-size-filter';
import { mapProxyName } from './http_proxy';

@@ -397,3 +396,2 @@ import { GrpcUri, parseUri, uriToString } from './uri-parser';

this.filterStackFactory = new FilterStackFactory([
new MaxMessageSizeFilterFactory(this.options),
new CompressionFilterFactory(this, this.options),

@@ -400,0 +398,0 @@ ]);

@@ -22,3 +22,2 @@ /*

import * as zlib from 'zlib';
import { promisify } from 'util';

@@ -42,4 +41,2 @@ import {

const TRACER_NAME = 'server_call';
const unzip = promisify(zlib.unzip);
const inflate = promisify(zlib.inflate);

@@ -485,15 +482,38 @@ function trace(text: string): void {

encoding: string
): Buffer | Promise<Buffer> {
if (encoding === 'deflate') {
return inflate(message.subarray(5));
} else if (encoding === 'gzip') {
return unzip(message.subarray(5));
} else if (encoding === 'identity') {
return message.subarray(5);
): Buffer | Promise<Buffer> { const messageContents = message.subarray(5);
if (encoding === 'identity') {
return messageContents;
} else if (encoding === 'deflate' || encoding === 'gzip') {
let decompresser: zlib.Gunzip | zlib.Deflate;
if (encoding === 'deflate') {
decompresser = zlib.createInflate();
} else {
decompresser = zlib.createGunzip();
}
return new Promise((resolve, reject) => {
let totalLength = 0
const messageParts: Buffer[] = [];
decompresser.on('data', (chunk: Buffer) => {
messageParts.push(chunk);
totalLength += chunk.byteLength;
if (this.maxReceiveMessageSize !== -1 && totalLength > this.maxReceiveMessageSize) {
decompresser.destroy();
reject({
code: Status.RESOURCE_EXHAUSTED,
details: `Received message that decompresses to a size larger than ${this.maxReceiveMessageSize}`
});
}
});
decompresser.on('end', () => {
resolve(Buffer.concat(messageParts));
});
decompresser.write(messageContents);
decompresser.end();
});
} else {
return Promise.reject({
code: Status.UNIMPLEMENTED,
details: `Received message compressed with unsupported encoding "${encoding}"`,
});
}
return Promise.reject({
code: Status.UNIMPLEMENTED,
details: `Received message compressed with unsupported encoding "${encoding}"`,
});
}

@@ -822,3 +842,3 @@

) {
const decoder = new StreamDecoder();
const decoder = new StreamDecoder(this.maxReceiveMessageSize);

@@ -839,3 +859,12 @@ let readsDone = false;

this.stream.on('data', async (data: Buffer) => {
const messages = decoder.write(data);
let messages: Buffer[];
try {
messages = decoder.write(data);
} catch (e) {
this.sendError({
code: Status.RESOURCE_EXHAUSTED,
details: (e as Error).message
});
return;
}

@@ -845,12 +874,2 @@ pendingMessageProcessing = true;

for (const message of messages) {
if (
this.maxReceiveMessageSize !== -1 &&
message.length > this.maxReceiveMessageSize
) {
this.sendError({
code: Status.RESOURCE_EXHAUSTED,
details: `Received message larger than max (${message.length} vs. ${this.maxReceiveMessageSize})`,
});
return;
}
this.emit('receiveMessage');

@@ -860,6 +879,12 @@

const compressedMessageEncoding = compressed ? encoding : 'identity';
const decompressedMessage = await this.getDecompressedMessage(
message,
compressedMessageEncoding
);
let decompressedMessage: Buffer;
try {
decompressedMessage = await this.getDecompressedMessage(
message,
compressedMessageEncoding
);
} catch (e) {
this.sendError(e as Partial<StatusObject>);
return;
}

@@ -866,0 +891,0 @@ // Encountered an error with decompression; it'll already have been propogated back

@@ -33,2 +33,4 @@ /*

constructor(private maxReadMessageLength: number) {}
write(data: Buffer): Buffer[] {

@@ -64,2 +66,5 @@ let readHead = 0;

this.readMessageSize = this.readPartialSize.readUInt32BE(0);
if (this.maxReadMessageLength !== -1 && this.readMessageSize > this.maxReadMessageLength) {
throw new Error(`Received message larger than max (${this.readMessageSize} vs ${this.maxReadMessageLength})`);
}
this.readMessageRemaining = this.readMessageSize;

@@ -66,0 +71,0 @@ if (this.readMessageRemaining > 0) {

@@ -21,3 +21,3 @@ /*

import { Status } from './constants';
import { DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH, Status } from './constants';
import { Metadata } from './metadata';

@@ -86,3 +86,3 @@ import { StreamDecoder } from './stream-decoder';

export class Http2SubchannelCall implements SubchannelCall {
private decoder = new StreamDecoder();
private decoder: StreamDecoder;

@@ -117,2 +117,4 @@ private isReadFilterPending = false;

) {
const maxReceiveMessageLength = transport.getOptions()['grpc.max_receive_message_length'] ?? DEFAULT_MAX_RECEIVE_MESSAGE_LENGTH;
this.decoder = new StreamDecoder(maxReceiveMessageLength);
http2Stream.on('response', (headers, flags) => {

@@ -175,3 +177,9 @@ let headersString = '';

this.trace('receive HTTP/2 data frame of length ' + data.length);
const messages = this.decoder.write(data);
let messages: Buffer[];
try {
messages = this.decoder.write(data);
} catch (e) {
this.cancelWithStatus(Status.RESOURCE_EXHAUSTED, (e as Error).message);
return;
}

@@ -178,0 +186,0 @@ for (const message of messages) {

@@ -86,2 +86,3 @@ /*

getPeerName(): string;
getOptions(): ChannelOptions;
createCall(

@@ -150,3 +151,3 @@ metadata: Metadata,

subchannelAddress: SubchannelAddress,
options: ChannelOptions,
private options: ChannelOptions,
/**

@@ -606,2 +607,6 @@ * Name of the remote server, if it is not the same as the subchannel

getOptions() {
return this.options;
}
shutdown() {

@@ -608,0 +613,0 @@ this.session.close();

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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