You're Invited:Meet the Socket Team at BlackHat and DEF CON in Las Vegas, Aug 7-8.RSVP
Socket
Socket
Sign inDemoInstall

mockttp

Package Overview
Dependencies
Maintainers
1
Versions
122
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 0.14.8 to 0.15.0

4

dist/client/mockttp-client.d.ts

@@ -7,3 +7,3 @@ /**

import { MockRuleData } from "../rules/mock-rule-types";
import { Mockttp, AbstractMockttp, MockttpOptions } from "../mockttp";
import { Mockttp, AbstractMockttp, MockttpOptions, PortRange } from "../mockttp";
export declare class ConnectionError extends TypedError {

@@ -40,3 +40,3 @@ }

private queryMockServer;
start(port?: number): Promise<void>;
start(portConfig?: number | PortRange): Promise<void>;
stop(): Promise<void>;

@@ -43,0 +43,0 @@ private typeHasField;

@@ -194,7 +194,7 @@ "use strict";

}
start(port) {
start(portConfig) {
return __awaiter(this, void 0, void 0, function* () {
if (this.mockServerConfig)
throw new Error('Server is already started');
const path = port ? `/start?port=${port}` : '/start';
const path = portConfig ? `/start?port=${JSON.stringify(portConfig)}` : '/start';
let mockServerConfig = yield this.requestFromStandalone(path, {

@@ -201,0 +201,0 @@ method: 'POST',

@@ -5,2 +5,6 @@ import MockRuleBuilder from "./rules/mock-rule-builder";

import { CAOptions } from './util/tls';
export declare type PortRange = {
startPort: number;
endPort: number;
};
/**

@@ -17,7 +21,11 @@ * A mockttp instance allow you to start and stop mock servers and control their behaviour.

*
* Specify a fixed port if you need one. If you don't, a random port will be chosen, which
* you can get later with `.port`, or by using `.url` and `.urlFor(path)` to generate
* your URLs automatically.
* Specify a fixed port if you need one.
*
* If you don't, a random port will be chosen, which you can get later with `.port`,
* or by using `.url` and `.urlFor(path)` to generate your URLs automatically.
*
* If you need to allow port selection, but in a specific range, pass a
* { startPort, endPort } pair to define the allowed (inclusive) range.
*/
start(port?: number): Promise<void>;
start(port?: number | PortRange): Promise<void>;
/**

@@ -24,0 +32,0 @@ * Stop the mock server and reset the rules.

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

const request_utils_1 = require("../server/request-utils");
const socket_util_1 = require("../util/socket-util");
const serialization_1 = require("../util/serialization");

@@ -311,2 +312,15 @@ function isSerializedBuffer(obj) {

let makeRequest = protocol === 'https:' ? https.request : http.request;
let family;
if (hostname === 'localhost') {
// Annoying special case: some localhost servers listen only on either ipv4 or ipv6.
// Very specific situation, but a very common one for development use.
// We need to work out which one family is, as Node sometimes makes bad choices.
const portToTest = !!port
? parseInt(port, 10)
: (protocol === 'https:' ? 443 : 80);
if (yield socket_util_1.isLocalPortActive('::1', portToTest))
family = 6;
else
family = 4;
}
let outgoingPort = null;

@@ -319,2 +333,3 @@ return new Promise((resolve, reject) => {

port,
family,
path,

@@ -352,4 +367,6 @@ headers,

});
clientReq.body.rawStream.pipe(serverReq);
clientReq.body.rawStream.once('error', () => serverReq.abort());
// asStream includes all content, including the body before this call
const reqBodyStream = clientReq.body.asStream();
reqBodyStream.pipe(serverReq);
reqBodyStream.once('error', () => serverReq.abort());
clientReq.once('abort', () => serverReq.abort());

@@ -356,0 +373,0 @@ clientRes.once('close', () => serverReq.abort());

@@ -51,5 +51,3 @@ "use strict";

const handlerArgs = arguments;
let completedAndRecordedPromise = ((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
// Start recording before the data starts piping, so we don't miss anything.
req.body.asBuffer();
let completedAndRecordedPromise = (() => __awaiter(this, void 0, void 0, function* () {
yield handler.apply(this, handlerArgs);

@@ -60,3 +58,3 @@ return request_utils_1.waitForCompletedRequest(req);

thisRule.requests.push(completedAndRecordedPromise);
return completedAndRecordedPromise.then(() => { });
return completedAndRecordedPromise;
}, {

@@ -63,0 +61,0 @@ explain: handler.explain

@@ -6,3 +6,3 @@ /**

import { MockRuleData } from "../rules/mock-rule-types";
import { Mockttp, AbstractMockttp, MockttpOptions } from "../mockttp";
import { Mockttp, AbstractMockttp, MockttpOptions, PortRange } from "../mockttp";
import { MockedEndpoint } from "./mocked-endpoint";

@@ -23,3 +23,3 @@ /**

constructor(options?: MockttpOptions);
start(portParam?: number): Promise<void>;
start(portParam?: number | PortRange): Promise<void>;
stop(): Promise<void>;

@@ -26,0 +26,0 @@ enableDebug(): void;

@@ -69,8 +69,10 @@ "use strict";

}
start(portParam) {
start(portParam = { startPort: 8000, endPort: 65535 }) {
return __awaiter(this, void 0, void 0, function* () {
if (!_.isInteger(portParam) && !_.isUndefined(portParam)) {
throw new Error(`Cannot start server with port ${portParam}. If passed, the port must be an integer`);
}
const port = (portParam || (yield portfinder.getPortPromise()));
const port = _.isNumber(portParam)
? portParam
: yield portfinder.getPortPromise({
port: portParam.startPort,
stopPort: portParam.endPort
});
if (this.debug)

@@ -77,0 +79,0 @@ console.log(`Starting mock server on port ${port}`);

@@ -28,19 +28,57 @@ "use strict";

};
// Takes a buffer and a stream, returns a simple stream that outputs the buffer then the stream.
const bufferThenStream = (buffer, inputStream) => {
const outputStream = new stream.PassThrough();
// Forward the buffered data so far
outputStream.write(Buffer.concat(buffer.currentChunks));
// After the data, forward errors from the buffer
if (buffer.failedWith) {
// Announce async, to ensure listeners have time to get set up
setTimeout(() => outputStream.emit('error', buffer.failedWith));
}
else {
// Forward future data as it arrives
inputStream.pipe(outputStream);
// Forward any future errors from the input stream
inputStream.once('error', (e) => outputStream.emit('error', e));
}
return outputStream;
};
const bufferToStream = (buffer) => {
const outputStream = new stream.PassThrough();
outputStream.end(buffer);
return outputStream;
};
const streamToBuffer = (input) => {
return new Promise((resolve, reject) => {
let chunks = [];
const chunks = [];
const bufferPromise = new Promise((resolve, reject) => {
input.on('data', (d) => chunks.push(d));
input.on('end', () => resolve(Buffer.concat(chunks)));
input.on('error', reject);
input.once('end', () => resolve(Buffer.concat(chunks)));
input.once('error', (e) => {
bufferPromise.failedWith = e;
reject(e);
});
});
bufferPromise.currentChunks = chunks;
return bufferPromise;
};
const parseBodyStream = (bodyStream) => {
let buffer = null;
let bufferPromise = null;
let completedBuffer = null;
let body = {
rawStream: bodyStream,
// Returns a stream for the full body, not the live streaming body.
// Each call creates a new stream, which starts with the already seen
// and buffered data, and then continues with the live stream, if active.
// Listeners to this stream *must* be attached synchronously after this call.
asStream() {
return completedBuffer
? bufferToStream(completedBuffer)
: bufferThenStream(body.asBuffer(), bodyStream);
},
asBuffer() {
if (!buffer) {
buffer = streamToBuffer(bodyStream);
if (!bufferPromise) {
bufferPromise = streamToBuffer(bodyStream);
bufferPromise.then((buffer) => completedBuffer = buffer);
}
return buffer;
return bufferPromise;
},

@@ -47,0 +85,0 @@ asText(encoding = 'utf8') {

@@ -63,6 +63,7 @@ "use strict";

try {
const port = req.query.port ?
parseInt(req.query.port, 10) : undefined;
const port = req.query.port
? JSON.parse(req.query.port)
: undefined;
const mockServerOptions = _.defaults({}, req.body, options.serverDefaults);
if (port != null && this.routers[port] != null) {
if (_.isNumber(port) && this.routers[port] != null) {
res.status(409).json({

@@ -135,3 +136,3 @@ error: `Cannot start: mock server is already running on port ${port}`

}
startMockServer(options, port) {
startMockServer(options, portConfig) {
return __awaiter(this, void 0, void 0, function* () {

@@ -141,3 +142,3 @@ const mockServer = new mockttp_server_1.default(_.defaults({

}, options));
yield mockServer.start(port);
yield mockServer.start(portConfig);
this.mockServers.push(mockServer);

@@ -144,0 +145,0 @@ const mockPort = mockServer.port;

@@ -50,3 +50,3 @@ /**

export interface ParsedBody {
rawStream: stream.Readable;
asStream: () => stream.Readable;
asBuffer: () => Promise<Buffer>;

@@ -53,0 +53,0 @@ asText: () => Promise<string>;

import * as net from 'net';
export declare function peekFirstByte(socket: net.Socket): Promise<number>;
export declare function mightBeTLSHandshake(byte: number): boolean;
export declare const isLocalIPv6Available: boolean;
export declare function isLocalPortActive(interfaceIp: '::1' | '127.0.0.1', port: number): Promise<{}>;

@@ -11,2 +11,5 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
const _ = require("lodash");
const os = require("os");
const net = require("net");
// Grab the first byte of a stream

@@ -31,2 +34,26 @@ // Note that this isn't a great abstraction: you might

exports.mightBeTLSHandshake = mightBeTLSHandshake;
exports.isLocalIPv6Available = _.some(os.networkInterfaces(), (addresses) => _.some(addresses, a => a.address === '::1'));
// Test if a local port for a given interface (IPv4/6) is currently in use
function isLocalPortActive(interfaceIp, port) {
return __awaiter(this, void 0, void 0, function* () {
if (interfaceIp === '::1' && !exports.isLocalIPv6Available)
return false;
return new Promise((resolve) => {
const server = net.createServer();
server.listen({
host: interfaceIp,
port,
ipv6Only: interfaceIp === '::1'
});
server.once('listening', () => {
resolve(false);
server.close(() => { });
});
server.once('error', (e) => {
resolve(true);
});
});
});
}
exports.isLocalPortActive = isLocalPortActive;
//# sourceMappingURL=socket-util.js.map
{
"name": "mockttp",
"version": "0.14.8",
"version": "0.15.0",
"description": "Mock HTTP server for testing HTTP clients and stubbing webservices",

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

@@ -23,3 +23,3 @@ /**

} from "../rules/mock-rule-types";
import { Mockttp, AbstractMockttp, MockttpOptions } from "../mockttp";
import { Mockttp, AbstractMockttp, MockttpOptions, PortRange } from "../mockttp";
import { MockServerConfig } from "../standalone/mockttp-standalone";

@@ -179,6 +179,6 @@ import { serializeRuleData } from "../rules/mock-rule";

async start(port?: number): Promise<void> {
async start(portConfig?: number | PortRange): Promise<void> {
if (this.mockServerConfig) throw new Error('Server is already started');
const path = port ? `/start?port=${port}` : '/start';
const path = portConfig ? `/start?port=${JSON.stringify(portConfig)}` : '/start';
let mockServerConfig = await this.requestFromStandalone<MockServerConfig>(path, {

@@ -185,0 +185,0 @@ method: 'POST',

@@ -11,5 +11,7 @@ /**

export type PortRange = { startPort: number, endPort: number };
/**
* A mockttp instance allow you to start and stop mock servers and control their behaviour.
*
*
* Call `.start()` to set up a server on a random port, use methods like `.get(url)`,

@@ -22,8 +24,12 @@ * `.post(url)` and `.anyRequest()` to get a {@link MockRuleBuilder} and start defining

* Start a mock server.
*
* Specify a fixed port if you need one. If you don't, a random port will be chosen, which
* you can get later with `.port`, or by using `.url` and `.urlFor(path)` to generate
* your URLs automatically.
*
* Specify a fixed port if you need one.
*
* If you don't, a random port will be chosen, which you can get later with `.port`,
* or by using `.url` and `.urlFor(path)` to generate your URLs automatically.
*
* If you need to allow port selection, but in a specific range, pass a
* { startPort, endPort } pair to define the allowed (inclusive) range.
*/
start(port?: number): Promise<void>;
start(port?: number | PortRange): Promise<void>;

@@ -30,0 +36,0 @@ /**

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

import { waitForCompletedRequest, setHeaders } from '../server/request-utils';
import { isLocalPortActive } from '../util/socket-util';
import { Serializable, SerializationOptions } from "../util/serialization";

@@ -436,2 +437,15 @@

let family: undefined | 4 | 6;
if (hostname === 'localhost') {
// Annoying special case: some localhost servers listen only on either ipv4 or ipv6.
// Very specific situation, but a very common one for development use.
// We need to work out which one family is, as Node sometimes makes bad choices.
const portToTest = !!port
? parseInt(port, 10)
: (protocol === 'https:' ? 443 : 80);
if (await isLocalPortActive('::1', portToTest)) family = 6;
else family = 4;
}
let outgoingPort: null | number = null;

@@ -444,2 +458,3 @@ return new Promise<void>((resolve, reject) => {

port,
family,
path,

@@ -482,4 +497,6 @@ headers,

clientReq.body.rawStream.pipe(serverReq);
clientReq.body.rawStream.once('error', () => serverReq.abort());
// asStream includes all content, including the body before this call
const reqBodyStream = clientReq.body.asStream();
reqBodyStream.pipe(serverReq);
reqBodyStream.once('error', () => serverReq.abort());
clientReq.once('abort', () => serverReq.abort());

@@ -486,0 +503,0 @@ clientRes.once('close', () => serverReq.abort());

@@ -71,8 +71,4 @@ /**

const handlerArgs = arguments;
let completedAndRecordedPromise = (async (resolve, reject) => {
// Start recording before the data starts piping, so we don't miss anything.
req.body.asBuffer();
let completedAndRecordedPromise = (async () => {
await handler.apply(this, <any> handlerArgs);
return waitForCompletedRequest(req);

@@ -84,3 +80,3 @@ })();

return completedAndRecordedPromise.then(() => {});
return completedAndRecordedPromise as Promise<any>;
}, {

@@ -87,0 +83,0 @@ explain: handler.explain

@@ -18,3 +18,3 @@ /**

import { DestroyableServer } from "../util/destroyable-server";
import { Mockttp, AbstractMockttp, MockttpOptions } from "../mockttp";
import { Mockttp, AbstractMockttp, MockttpOptions, PortRange } from "../mockttp";
import { MockRule } from "../rules/mock-rule";

@@ -73,9 +73,10 @@ import { MockedEndpoint } from "./mocked-endpoint";

async start(portParam?: number): Promise<void> {
if (!_.isInteger(portParam) && !_.isUndefined(portParam)) {
throw new Error(`Cannot start server with port ${portParam}. If passed, the port must be an integer`);
}
async start(portParam: number | PortRange = { startPort: 8000, endPort: 65535 }): Promise<void> {
const port = _.isNumber(portParam)
? portParam
: await portfinder.getPortPromise({
port: portParam.startPort,
stopPort: portParam.endPort
});
const port = (portParam || await portfinder.getPortPromise());
if (this.debug) console.log(`Starting mock server on port ${port}`);

@@ -82,0 +83,0 @@

@@ -33,22 +33,68 @@ /**

const streamToBuffer = (input: stream.Readable): Promise<Buffer> => {
return new Promise((resolve, reject) => {
let chunks: Buffer[] = [];
input.on('data', (d: Buffer) => chunks.push(d));
input.on('end', () => resolve(Buffer.concat(chunks)));
input.on('error', reject);
});
}
// Takes a buffer and a stream, returns a simple stream that outputs the buffer then the stream.
const bufferThenStream = (buffer: BufferInProgress, inputStream: stream.Readable): stream.Readable => {
const outputStream = new stream.PassThrough();
// Forward the buffered data so far
outputStream.write(Buffer.concat(buffer.currentChunks));
// After the data, forward errors from the buffer
if (buffer.failedWith) {
// Announce async, to ensure listeners have time to get set up
setTimeout(() => outputStream.emit('error', buffer.failedWith));
} else {
// Forward future data as it arrives
inputStream.pipe(outputStream);
// Forward any future errors from the input stream
inputStream.once('error', (e) => outputStream.emit('error', e));
}
return outputStream;
};
const bufferToStream = (buffer: Buffer): stream.Readable => {
const outputStream = new stream.PassThrough();
outputStream.end(buffer);
return outputStream;
};
type BufferInProgress = Promise<Buffer> & {
currentChunks: Buffer[] // Stores the body chunks as they arrive
failedWith?: Error // Stores the error that killed the stream, if one did
};
const streamToBuffer = (input: stream.Readable) => {
const chunks: Buffer[] = [];
const bufferPromise = <BufferInProgress> new Promise(
(resolve, reject) => {
input.on('data', (d: Buffer) => chunks.push(d));
input.once('end', () => resolve(Buffer.concat(chunks)));
input.once('error', (e) => {
bufferPromise.failedWith = e;
reject(e);
});
}
);
bufferPromise.currentChunks = chunks;
return bufferPromise;
};
const parseBodyStream = (bodyStream: stream.Readable): ParsedBody => {
let buffer: Promise<Buffer> | null = null;
let bufferPromise: BufferInProgress | null = null;
let completedBuffer: Buffer | null = null;
let body = {
rawStream: bodyStream,
// Returns a stream for the full body, not the live streaming body.
// Each call creates a new stream, which starts with the already seen
// and buffered data, and then continues with the live stream, if active.
// Listeners to this stream *must* be attached synchronously after this call.
asStream() {
return completedBuffer
? bufferToStream(completedBuffer)
: bufferThenStream(body.asBuffer(), bodyStream);
},
asBuffer() {
if (!buffer) {
buffer = streamToBuffer(bodyStream);
if (!bufferPromise) {
bufferPromise = streamToBuffer(bodyStream);
bufferPromise.then((buffer) => completedBuffer = buffer);
}
return buffer;
return bufferPromise;
},

@@ -55,0 +101,0 @@ asText(encoding = 'utf8') {

@@ -28,3 +28,3 @@ /**

import { DEFAULT_STANDALONE_PORT } from '../types';
import { MockttpOptions } from '../mockttp';
import { MockttpOptions, PortRange } from '../mockttp';
import { Duplex } from 'stream';

@@ -70,4 +70,5 @@

try {
const port: number | undefined = req.query.port ?
parseInt(req.query.port, 10) : undefined;
const port: number | PortRange | undefined = req.query.port
? JSON.parse(req.query.port)
: undefined;
const mockServerOptions: MockttpOptions = _.defaults(

@@ -79,3 +80,3 @@ {},

if (port != null && this.routers[port] != null) {
if (_.isNumber(port) && this.routers[port] != null) {
res.status(409).json({

@@ -163,3 +164,3 @@ error: `Cannot start: mock server is already running on port ${port}`

private async startMockServer(options: MockttpOptions, port?: number): Promise<{
private async startMockServer(options: MockttpOptions, portConfig?: number | PortRange): Promise<{
mockPort: number,

@@ -171,3 +172,3 @@ mockServer: MockttpServer

}, options));
await mockServer.start(port);
await mockServer.start(portConfig);
this.mockServers.push(mockServer);

@@ -174,0 +175,0 @@

@@ -66,4 +66,3 @@ /**

export interface ParsedBody {
rawStream: stream.Readable;
asStream: () => stream.Readable;
asBuffer: () => Promise<Buffer>;

@@ -70,0 +69,0 @@ asText: () => Promise<string>;

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

import * as _ from 'lodash';
import * as os from 'os';
import * as net from 'net';

@@ -18,2 +20,27 @@

return byte === 22;
}
export const isLocalIPv6Available = _.some(os.networkInterfaces(),
(addresses) => _.some(addresses, a => a.address === '::1')
);
// Test if a local port for a given interface (IPv4/6) is currently in use
export async function isLocalPortActive(interfaceIp: '::1' | '127.0.0.1', port: number) {
if (interfaceIp === '::1' && !isLocalIPv6Available) return false;
return new Promise((resolve) => {
const server = net.createServer();
server.listen({
host: interfaceIp,
port,
ipv6Only: interfaceIp === '::1'
});
server.once('listening', () => {
resolve(false);
server.close(() => {});
});
server.once('error', (e) => {
resolve(true);
});
});
}

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 too big to display

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

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

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc