Socket
Socket
Sign inDemoInstall

@hocuspocus/server

Package Overview
Dependencies
Maintainers
3
Versions
114
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@hocuspocus/server - npm Package Compare versions

Comparing version 1.0.0-alpha.63 to 1.0.0-alpha.64

dist/packages/server/src/MessageReceiver.d.ts

12

CHANGELOG.md

@@ -6,2 +6,14 @@ # Change Log

# [1.0.0-alpha.64](https://github.com/ueberdosis/hocuspocus/compare/@hocuspocus/server@1.0.0-alpha.63...@hocuspocus/server@1.0.0-alpha.64) (2021-08-27)
### Bug Fixes
* Empty sync message causes error in client MessageReceiver ([#174](https://github.com/ueberdosis/hocuspocus/issues/174)) ([f9dca69](https://github.com/ueberdosis/hocuspocus/commit/f9dca69eb96d1ede37a0709bd3b7735bf1ff57ba))
* Potential onCreateDocument race condition ([#167](https://github.com/ueberdosis/hocuspocus/issues/167)) ([b3e3e4d](https://github.com/ueberdosis/hocuspocus/commit/b3e3e4dea74f9b833ccb0c6a6521f55c001411c1))
# [1.0.0-alpha.63](https://github.com/ueberdosis/hocuspocus/compare/@hocuspocus/server@1.0.0-alpha.62...@hocuspocus/server@1.0.0-alpha.63) (2021-08-19)

@@ -8,0 +20,0 @@

160

dist/hocuspocus-server.esm.js

@@ -423,2 +423,3 @@ import WebSocket from 'ws';

(function (MessageType) {
MessageType[MessageType["Unknown"] = -1] = "Unknown";
MessageType[MessageType["Sync"] = 0] = "Sync";

@@ -1260,11 +1261,50 @@ MessageType[MessageType["Awareness"] = 1] = "Awareness";

}
this.encoder = createEncoder();
this.decoder = createDecoder(input);
}
readSyncMessageAndApplyItTo(document, connection) {
writeVarUint(this.encoder, MessageType.Sync);
// this is a copy of the original y-protocols/sync/readSyncMessage function
// which enables the read only mode
switch (this.type) {
readVarUint8Array() {
return readVarUint8Array(this.decoder);
}
readVarUint() {
return readVarUint(this.decoder);
}
toUint8Array() {
return toUint8Array(this.encoder);
}
writeVarUint(type) {
writeVarUint(this.encoder, type);
}
get length() {
return length$1(this.encoder);
}
}
class MessageReceiver {
constructor(message) {
this.message = message;
}
apply(connection) {
const { document } = connection;
const { message } = this;
const type = message.readVarUint();
switch (type) {
case MessageType.Sync:
message.writeVarUint(MessageType.Sync);
this.readSyncMessage(message, connection);
if (message.length > 1) {
connection.send(message.toUint8Array());
}
break;
case MessageType.Awareness:
applyAwarenessUpdate(document.awareness, message.readVarUint8Array(), connection);
break;
// Do nothing
}
}
readSyncMessage(message, connection) {
const { document } = connection;
const type = message.readVarUint();
switch (type) {
case messageYjsSyncStep1:
readSyncStep1(this.decoder, this.encoder, document);
readSyncStep1(message.decoder, message.encoder, document);
break;

@@ -1275,3 +1315,3 @@ case messageYjsSyncStep2:

}
readSyncStep2(this.decoder, document, connection);
readSyncStep2(message.decoder, document, null);
break;

@@ -1282,33 +1322,9 @@ case messageYjsUpdate:

}
readUpdate(this.decoder, document, connection);
readUpdate(message.decoder, document, null);
break;
// TODO: Shouldn’t crash the whole server,
// remove or catch exceptions in the top level?
// throw new Error('Unknown message type')
default:
throw new Error(`Received a message with an unknown type: ${type}`);
}
return type;
}
readUint8Array() {
return readVarUint8Array(this.decoder);
}
toUint8Array() {
return toUint8Array(this.encoder);
}
get length() {
return length$1(this.encoder);
}
get type() {
try {
return readVarUint(this.decoder);
}
catch {
// Failed read the message type
return -1;
}
}
get encoder() {
if (!this.syncMessageEncoder) {
this.syncMessageEncoder = createEncoder();
}
return this.syncMessageEncoder;
}
}

@@ -1421,13 +1437,4 @@

*/
handleMessage(input) {
const message = new IncomingMessage(input);
if (message.type === MessageType.Awareness) {
this.document.applyAwarenessUpdate(this, message.readUint8Array());
return;
}
message.readSyncMessageAndApplyItTo(this.document, this);
if (message.length <= 1) {
return;
}
return this.send(message.toUint8Array());
handleMessage(data) {
new MessageReceiver(new IncomingMessage(data)).apply(this);
}

@@ -1449,3 +1456,3 @@ /**

var description = "plug & play collaboration backend";
var version = "1.0.0-alpha.62";
var version = "1.0.0-alpha.63";
var homepage = "https://hocuspocus.dev";

@@ -1551,3 +1558,5 @@ var keywords = [

get authenticationRequired() {
return this.configuration.onAuthenticate !== undefined;
return !!this.configuration.extensions.find(extension => {
return extension.onAuthenticate !== undefined;
});
}

@@ -1722,34 +1731,29 @@ /**

async createDocument(documentName, request, socketId, context) {
return new Promise(resolve => {
if (this.documents.has(documentName)) {
const document = this.documents.get(documentName);
return resolve(document);
if (this.documents.has(documentName)) {
const document = this.documents.get(documentName);
return document;
}
const document = new Document(documentName);
this.documents.set(documentName, document);
const hookPayload = {
context,
document,
documentName,
socketId,
requestHeaders: request.headers,
requestParameters: Hocuspocus.getParameters(request),
};
await this.hooks('onCreateDocument', hookPayload, (loadedDocument) => {
// if a hook returns a Y-Doc, encode the document state as update
// and apply it to the newly created document
// Note: instanceof doesn't work, because Doc !== Doc for some reason I don't understand
if ((loadedDocument === null || loadedDocument === void 0 ? void 0 : loadedDocument.constructor.name) === 'Document'
|| (loadedDocument === null || loadedDocument === void 0 ? void 0 : loadedDocument.constructor.name) === 'Doc') {
applyUpdate(document, encodeStateAsUpdate(loadedDocument));
}
const document = new Document(documentName);
document.onUpdate((document, connection, update) => {
this.handleDocumentUpdate(document, connection, update, request, connection === null || connection === void 0 ? void 0 : connection.socketId);
});
const hookPayload = {
context,
document,
documentName,
socketId,
requestHeaders: request.headers,
requestParameters: Hocuspocus.getParameters(request),
};
this.hooks('onCreateDocument', hookPayload, (loadedDocument) => {
// if a hook returns a Y-Doc, encode the document state as update
// and apply it to the newly created document
// Note: instanceof doesn't work, because Doc !== Doc for some reason I don't understand
if ((loadedDocument === null || loadedDocument === void 0 ? void 0 : loadedDocument.constructor.name) === 'Document'
|| (loadedDocument === null || loadedDocument === void 0 ? void 0 : loadedDocument.constructor.name) === 'Doc') {
applyUpdate(document, encodeStateAsUpdate(loadedDocument));
}
}).then(() => {
resolve(document);
}).catch(e => {
throw e;
});
this.documents.set(documentName, document);
});
document.onUpdate((document, connection, update) => {
this.handleDocumentUpdate(document, connection, update, request, connection === null || connection === void 0 ? void 0 : connection.socketId);
});
return document;
}

@@ -1756,0 +1760,0 @@ /**

/// <reference types="node" />
import { Extension, onChangePayload, onConfigurePayload, onConnectPayload, onCreateDocumentPayload, onDestroyPayload, onDisconnectPayload, onListenPayload, onRequestPayload, onUpgradePayload } from '@hocuspocus/server';
import { Extension, onChangePayload, onConfigurePayload, onConnectPayload, onCreateDocumentPayload, onDisconnectPayload, onRequestPayload, onUpgradePayload } from '@hocuspocus/server';
import { IncomingMessage, ServerResponse } from 'http';

@@ -37,5 +37,3 @@ import WebSocket from 'ws';

onChange(data: onChangePayload): Promise<void>;
onListen(data: onListenPayload): Promise<void>;
onDestroy(data: onDestroyPayload): Promise<void>;
onConfigure(data: onConfigurePayload): Promise<void>;
}

@@ -41,2 +41,3 @@ import * as Y from 'yjs';

onDestroy: () => void;
onAwarenessUpdate: (states: any) => void;
onAwarenessChange: (states: any) => void;

@@ -43,0 +44,0 @@ debug: boolean;

@@ -1,11 +0,13 @@

import * as decoding from 'lib0/decoding';
import * as encoding from 'lib0/encoding';
import { Decoder } from 'lib0/decoding';
import { Encoder } from 'lib0/encoding';
import { MessageType } from './types';
export declare class IncomingMessage {
data: any;
encoder: encoding.Encoder;
decoder: decoding.Decoder;
type: MessageType;
encoder: Encoder;
decoder: Decoder;
constructor(data: any);
get name(): string;
readVarUint(): MessageType;
readVarUint8Array(): Uint8Array;
writeVarUint(type: MessageType): void;
writeVarUint8Array(data: Uint8Array): void;
}

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

import * as encoding from 'lib0/encoding';
import { HocuspocusProvider } from './HocuspocusProvider';

@@ -7,3 +6,3 @@ import { IncomingMessage } from './IncomingMessage';

constructor(message: IncomingMessage);
apply(provider: HocuspocusProvider, emitSynced?: boolean): encoding.Encoder;
apply(provider: HocuspocusProvider, emitSynced?: boolean): void;
private applySyncMessage;

@@ -10,0 +9,0 @@ private applyAwarenessMessage;

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

import * as encoding from 'lib0/encoding';
import { Encoder } from 'lib0/encoding';
import { AuthenticationMessage } from './OutgoingMessages/AuthenticationMessage';

@@ -10,3 +10,3 @@ import { AwarenessMessage } from './OutgoingMessages/AwarenessMessage';

export declare class MessageSender {
encoder: encoding.Encoder;
encoder: Encoder;
message: any;

@@ -13,0 +13,0 @@ constructor(Message: Constructable<AuthenticationMessage> | Constructable<AwarenessMessage> | Constructable<QueryAwarenessMessage> | Constructable<SyncStepOneMessage> | Constructable<SyncStepTwoMessage> | Constructable<UpdateMessage>, args?: any);

@@ -1,8 +0,8 @@

import * as encoding from 'lib0/encoding';
import { Encoder } from 'lib0/encoding';
import { MessageType, OutgoingMessageInterface } from './types';
export declare class OutgoingMessage implements OutgoingMessageInterface {
encoder: encoding.Encoder;
encoder: Encoder;
type?: MessageType;
constructor();
get name(): string;
toUint8Array(): Uint8Array;
}

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

import * as encoding from 'lib0/encoding';
import { MessageType, OutgoingMessageArguments } from '../types';

@@ -7,3 +6,3 @@ import { OutgoingMessage } from '../OutgoingMessage';

description: string;
get(args: Partial<OutgoingMessageArguments>): encoding.Encoder;
get(args: Partial<OutgoingMessageArguments>): import("lib0/encoding").Encoder;
}

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

import * as encoding from 'lib0/encoding';
import { MessageType, OutgoingMessageArguments } from '../types';

@@ -7,3 +6,3 @@ import { OutgoingMessage } from '../OutgoingMessage';

description: string;
get(args: Partial<OutgoingMessageArguments>): encoding.Encoder;
get(args: Partial<OutgoingMessageArguments>): import("lib0/encoding").Encoder;
}
import { RedisPersistence } from 'y-redis';
import { Extension, onChangePayload, onConfigurePayload, onConnectPayload, onCreateDocumentPayload, onDestroyPayload, onDisconnectPayload, onListenPayload, onRequestPayload, onUpgradePayload } from '@hocuspocus/server';
import { Extension, onConnectPayload, onCreateDocumentPayload, onDisconnectPayload } from '@hocuspocus/server';
export interface Configuration {

@@ -15,9 +15,3 @@ }

onConnect(data: onConnectPayload): Promise<void>;
onChange(data: onChangePayload): Promise<void>;
onDisconnect(data: onDisconnectPayload): Promise<void>;
onListen(data: onListenPayload): Promise<void>;
onDestroy(data: onDestroyPayload): Promise<void>;
onConfigure(data: onConfigurePayload): Promise<void>;
onRequest(data: onRequestPayload): Promise<void>;
onUpgrade(data: onUpgradePayload): Promise<void>;
}

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

import { Extension, onChangePayload, onConfigurePayload, onConnectPayload, onCreateDocumentPayload, onDestroyPayload, onDisconnectPayload, onListenPayload, onRequestPayload, onUpgradePayload } from '@hocuspocus/server';
import { Extension, onCreateDocumentPayload } from '@hocuspocus/server';
import { LeveldbPersistence } from 'y-leveldb';

@@ -22,10 +22,2 @@ export interface Configuration {

store(documentName: string, update: Uint8Array): Promise<any>;
onChange(data: onChangePayload): Promise<void>;
onConnect(data: onConnectPayload): Promise<void>;
onDisconnect(data: onDisconnectPayload): Promise<void>;
onListen(data: onListenPayload): Promise<void>;
onDestroy(data: onDestroyPayload): Promise<void>;
onConfigure(data: onConfigurePayload): Promise<void>;
onRequest(data: onRequestPayload): Promise<void>;
onUpgrade(data: onUpgradePayload): Promise<void>;
}
import { Decoder } from 'lib0/decoding';
import { Encoder } from 'lib0/encoding';
import Document from './Document';
import Connection from './Connection';
import { MessageType } from './types';
export declare class IncomingMessage {
/**
* Access to the received message.
*/
decoder: Decoder;
syncMessageEncoder?: Encoder;
/**
* Access to the reply.
*/
encoder: Encoder;
constructor(input: any);
readSyncMessageAndApplyItTo(document: Document, connection?: Connection): void;
readUint8Array(): Uint8Array;
readVarUint8Array(): Uint8Array;
readVarUint(): number;
toUint8Array(): Uint8Array;
writeVarUint(type: MessageType): void;
get length(): number;
get type(): number;
private get encoder();
}

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

export declare enum MessageType {
Unknown = -1,
Sync = 0,

@@ -23,11 +24,11 @@ Awareness = 1,

onAuthenticate?(data: onAuthenticatePayload): Promise<any>;
onChange(data: onChangePayload): Promise<any>;
onConnect(data: onConnectPayload): Promise<any>;
onConfigure(data: onConfigurePayload): Promise<any>;
onCreateDocument(data: onCreateDocumentPayload): Promise<any>;
onDestroy(data: onDestroyPayload): Promise<any>;
onDisconnect(data: onDisconnectPayload): Promise<any>;
onListen(data: onListenPayload): Promise<any>;
onRequest(data: onRequestPayload): Promise<any>;
onUpgrade(data: onUpgradePayload): Promise<any>;
onChange?(data: onChangePayload): Promise<any>;
onConnect?(data: onConnectPayload): Promise<any>;
onConfigure?(data: onConfigurePayload): Promise<any>;
onCreateDocument?(data: onCreateDocumentPayload): Promise<any>;
onDestroy?(data: onDestroyPayload): Promise<any>;
onDisconnect?(data: onDisconnectPayload): Promise<any>;
onListen?(data: onListenPayload): Promise<any>;
onRequest?(data: onRequestPayload): Promise<any>;
onUpgrade?(data: onUpgradePayload): Promise<any>;
}

@@ -34,0 +35,0 @@ export interface Configuration extends Extension {

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

import { Extension, onChangePayload, onConfigurePayload, onConnectPayload, onCreateDocumentPayload, onDestroyPayload, onDisconnectPayload, onListenPayload, onRequestPayload, onUpgradePayload } from '@hocuspocus/server';
import { Extension, onConnectPayload } from '@hocuspocus/server';
export interface Configuration {

@@ -20,10 +20,2 @@ throttle: number | null | false;

onConnect(data: onConnectPayload): Promise<any>;
onCreateDocument(data: onCreateDocumentPayload): Promise<void>;
onChange(data: onChangePayload): Promise<void>;
onDisconnect(data: onDisconnectPayload): Promise<void>;
onUpgrade(data: onUpgradePayload): Promise<void>;
onRequest(data: onRequestPayload): Promise<void>;
onListen(data: onListenPayload): Promise<void>;
onDestroy(data: onDestroyPayload): Promise<void>;
onConfigure(data: onConfigurePayload): Promise<void>;
}
/// <reference types="node" />
import { Extension, onChangePayload, onConfigurePayload, onConnectPayload, onCreateDocumentPayload, onDestroyPayload, onDisconnectPayload, onListenPayload, onRequestPayload, onUpgradePayload } from '@hocuspocus/server';
import { Extension, onChangePayload, onConnectPayload, onCreateDocumentPayload, onDisconnectPayload } from '@hocuspocus/server';
import { Doc } from 'yjs';

@@ -59,7 +59,2 @@ import { Transformer } from '@hocuspocus/transformer';

onDisconnect(data: onDisconnectPayload): Promise<void>;
onUpgrade(data: onUpgradePayload): Promise<void>;
onRequest(data: onRequestPayload): Promise<void>;
onListen(data: onListenPayload): Promise<void>;
onDestroy(data: onDestroyPayload): Promise<void>;
onConfigure(data: onConfigurePayload): Promise<void>;
}
{
"name": "@hocuspocus/server",
"description": "plug & play collaboration backend",
"version": "1.0.0-alpha.63",
"version": "1.0.0-alpha.64",
"homepage": "https://hocuspocus.dev",

@@ -35,3 +35,3 @@ "keywords": [

},
"gitHead": "13bb2b38c5887bb09c2b6565754888092c8e345b"
"gitHead": "d8938e5d42a85a8d447e7e63fd5e2bf4f18a7d2d"
}

@@ -7,4 +7,5 @@ import AsyncLock from 'async-lock'

import { IncomingMessage } from './IncomingMessage'
import { MessageType, WsReadyStates } from './types'
import { WsReadyStates } from './types'
import { OutgoingMessage } from './OutgoingMessage'
import { MessageReceiver } from './MessageReceiver'

@@ -170,20 +171,6 @@ class Connection {

*/
private handleMessage(input: Iterable<number>): void {
const message = new IncomingMessage(input)
if (message.type === MessageType.Awareness) {
this.document.applyAwarenessUpdate(this, message.readUint8Array())
return
}
message.readSyncMessageAndApplyItTo(this.document, this)
if (message.length <= 1) {
return
}
return this.send(
message.toUint8Array(),
)
private handleMessage(data: Iterable<number>): void {
new MessageReceiver(
new IncomingMessage(data),
).apply(this)
}

@@ -190,0 +177,0 @@

@@ -79,3 +79,5 @@ import * as decoding from 'lib0/decoding'

get authenticationRequired(): boolean {
return this.configuration.onAuthenticate !== undefined
return !!this.configuration.extensions.find(extension => {
return extension.onAuthenticate !== undefined
})
}

@@ -279,41 +281,36 @@

private async createDocument(documentName: string, request: IncomingMessage, socketId: string, context?: any): Promise<Document> {
return new Promise(resolve => {
if (this.documents.has(documentName)) {
const document = this.documents.get(documentName)
return resolve(document)
}
if (this.documents.has(documentName)) {
const document = this.documents.get(documentName)
return document
}
const document = new Document(documentName)
const document = new Document(documentName)
this.documents.set(documentName, document)
document.onUpdate((document, connection, update) => {
this.handleDocumentUpdate(document, connection, update, request, connection?.socketId)
})
const hookPayload = {
context,
document,
documentName,
socketId,
requestHeaders: request.headers,
requestParameters: Hocuspocus.getParameters(request),
}
const hookPayload = {
context,
document,
documentName,
socketId,
requestHeaders: request.headers,
requestParameters: Hocuspocus.getParameters(request),
}
this.hooks('onCreateDocument', hookPayload, (loadedDocument: Doc | undefined) => {
await this.hooks('onCreateDocument', hookPayload, (loadedDocument: Doc | undefined) => {
// if a hook returns a Y-Doc, encode the document state as update
// and apply it to the newly created document
// Note: instanceof doesn't work, because Doc !== Doc for some reason I don't understand
if (
loadedDocument?.constructor.name === 'Document'
if (
loadedDocument?.constructor.name === 'Document'
|| loadedDocument?.constructor.name === 'Doc'
) {
applyUpdate(document, encodeStateAsUpdate(loadedDocument))
}
}).then(() => {
resolve(document)
}).catch(e => {
throw e
})
) {
applyUpdate(document, encodeStateAsUpdate(loadedDocument))
}
})
this.documents.set(documentName, document)
document.onUpdate((document: Document, connection: Connection, update: Uint8Array) => {
this.handleDocumentUpdate(document, connection, update, request, connection?.socketId)
})
return document
}

@@ -320,0 +317,0 @@

@@ -10,24 +10,18 @@ import {

Encoder,
toUint8Array,
writeVarUint,
length,
writeVarUint,
toUint8Array,
} from 'lib0/encoding'
import {
messageYjsSyncStep1,
messageYjsSyncStep2,
messageYjsUpdate,
readSyncStep1,
readSyncStep2,
readUpdate,
} from 'y-protocols/sync'
import Document from './Document'
import { MessageType } from './types'
import Connection from './Connection'
export class IncomingMessage {
/**
* Access to the received message.
*/
decoder: Decoder
syncMessageEncoder?: Encoder
/**
* Access to the reply.
*/
encoder: Encoder

@@ -39,66 +33,25 @@ constructor(input: any) {

this.encoder = createEncoder()
this.decoder = createDecoder(input)
}
readSyncMessageAndApplyItTo(document: Document, connection?: Connection): void {
writeVarUint(this.encoder, MessageType.Sync)
// this is a copy of the original y-protocols/sync/readSyncMessage function
// which enables the read only mode
switch (this.type) {
case messageYjsSyncStep1:
readSyncStep1(this.decoder, this.encoder, document)
break
case messageYjsSyncStep2:
if (connection?.readOnly) {
break
}
readSyncStep2(this.decoder, document, connection)
break
case messageYjsUpdate:
if (connection?.readOnly) {
break
}
readUpdate(this.decoder, document, connection)
break
default:
// TODO: Shouldn’t crash the whole server,
// remove or catch exceptions in the top level?
// throw new Error('Unknown message type')
}
readVarUint8Array() {
return readVarUint8Array(this.decoder)
}
readUint8Array(): Uint8Array {
return readVarUint8Array(this.decoder)
readVarUint() {
return readVarUint(this.decoder)
}
toUint8Array(): Uint8Array {
toUint8Array() {
return toUint8Array(this.encoder)
}
writeVarUint(type: MessageType) {
writeVarUint(this.encoder, type)
}
get length(): number {
return length(this.encoder)
}
get type(): number {
try {
return readVarUint(this.decoder)
} catch {
// Failed read the message type
return -1
}
}
private get encoder() {
if (!this.syncMessageEncoder) {
this.syncMessageEncoder = createEncoder()
}
return this.syncMessageEncoder
}
}

@@ -9,2 +9,3 @@ import {

export enum MessageType {
Unknown = -1,
Sync = 0,

@@ -28,11 +29,11 @@ Awareness = 1,

onAuthenticate?(data: onAuthenticatePayload): Promise<any>,
onChange(data: onChangePayload): Promise<any>,
onConnect(data: onConnectPayload): Promise<any>,
onConfigure(data: onConfigurePayload): Promise<any>,
onCreateDocument(data: onCreateDocumentPayload): Promise<any>,
onDestroy(data: onDestroyPayload): Promise<any>,
onDisconnect(data: onDisconnectPayload): Promise<any>
onListen(data: onListenPayload): Promise<any>,
onRequest(data: onRequestPayload): Promise<any>,
onUpgrade(data: onUpgradePayload): Promise<any>,
onChange?(data: onChangePayload): Promise<any>,
onConnect?(data: onConnectPayload): Promise<any>,
onConfigure?(data: onConfigurePayload): Promise<any>,
onCreateDocument?(data: onCreateDocumentPayload): Promise<any>,
onDestroy?(data: onDestroyPayload): Promise<any>,
onDisconnect?(data: onDisconnectPayload): Promise<any>
onListen?(data: onListenPayload): Promise<any>,
onRequest?(data: onRequestPayload): Promise<any>,
onUpgrade?(data: onUpgradePayload): Promise<any>,
}

@@ -39,0 +40,0 @@

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