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

nostr-tools

Package Overview
Dependencies
Maintainers
1
Versions
151
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

nostr-tools - npm Package Compare versions

Comparing version 2.1.4 to 2.1.5

lib/cjs/nip94.js

2

lib/cjs/abstract-pool.js

@@ -92,2 +92,4 @@ "use strict";

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -94,0 +96,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -93,2 +93,4 @@ "use strict";

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -95,0 +97,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

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

FileMetadata: () => FileMetadata,
FileServerPreference: () => FileServerPreference,
Followsets: () => Followsets,

@@ -168,2 +169,3 @@ GenericRepost: () => GenericRepost,

var UserEmojiList = 10030;
var FileServerPreference = 10096;
var NWCWalletInfo = 13194;

@@ -170,0 +172,0 @@ var LightningPubRPC = 21e3;

@@ -23,8 +23,222 @@ "use strict";

__export(nip29_exports, {
encodeGroupReference: () => encodeGroupReference,
loadGroup: () => loadGroup,
loadGroupFromCode: () => loadGroupFromCode,
parseGroup: () => parseGroup,
parseMembers: () => parseMembers
parseGroupCode: () => parseGroupCode,
parseMembers: () => parseMembers,
subscribeRelayGroups: () => subscribeRelayGroups
});
module.exports = __toCommonJS(nip29_exports);
function parseGroup(event) {
const chan = {};
// nip19.ts
var import_utils = require("@noble/hashes/utils");
var import_base = require("@scure/base");
// utils.ts
var utf8Decoder = new TextDecoder("utf-8");
var utf8Encoder = new TextEncoder();
function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);
p.pathname = p.pathname.replace(/\/+/g, "/");
if (p.pathname.endsWith("/"))
p.pathname = p.pathname.slice(0, -1);
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
p.port = "";
p.searchParams.sort();
p.hash = "";
return p.toString();
}
// nip19.ts
var Bech32MaxSize = 5e3;
function decode(nip19) {
let { prefix, words } = import_base.bech32.decode(nip19, Bech32MaxSize);
let data = new Uint8Array(import_base.bech32.fromWords(words));
switch (prefix) {
case "nprofile": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for nprofile");
if (tlv[0][0].length !== 32)
throw new Error("TLV 0 should be 32 bytes");
return {
type: "nprofile",
data: {
pubkey: (0, import_utils.bytesToHex)(tlv[0][0]),
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
}
};
}
case "nevent": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for nevent");
if (tlv[0][0].length !== 32)
throw new Error("TLV 0 should be 32 bytes");
if (tlv[2] && tlv[2][0].length !== 32)
throw new Error("TLV 2 should be 32 bytes");
if (tlv[3] && tlv[3][0].length !== 4)
throw new Error("TLV 3 should be 4 bytes");
return {
type: "nevent",
data: {
id: (0, import_utils.bytesToHex)(tlv[0][0]),
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
author: tlv[2]?.[0] ? (0, import_utils.bytesToHex)(tlv[2][0]) : void 0,
kind: tlv[3]?.[0] ? parseInt((0, import_utils.bytesToHex)(tlv[3][0]), 16) : void 0
}
};
}
case "naddr": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for naddr");
if (!tlv[2]?.[0])
throw new Error("missing TLV 2 for naddr");
if (tlv[2][0].length !== 32)
throw new Error("TLV 2 should be 32 bytes");
if (!tlv[3]?.[0])
throw new Error("missing TLV 3 for naddr");
if (tlv[3][0].length !== 4)
throw new Error("TLV 3 should be 4 bytes");
return {
type: "naddr",
data: {
identifier: utf8Decoder.decode(tlv[0][0]),
pubkey: (0, import_utils.bytesToHex)(tlv[2][0]),
kind: parseInt((0, import_utils.bytesToHex)(tlv[3][0]), 16),
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
}
};
}
case "nrelay": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for nrelay");
return {
type: "nrelay",
data: utf8Decoder.decode(tlv[0][0])
};
}
case "nsec":
return { type: prefix, data };
case "npub":
case "note":
return { type: prefix, data: (0, import_utils.bytesToHex)(data) };
default:
throw new Error(`unknown prefix ${prefix}`);
}
}
function parseTLV(data) {
let result = {};
let rest = data;
while (rest.length > 0) {
let t = rest[0];
let l = rest[1];
let v = rest.slice(2, 2 + l);
rest = rest.slice(2 + l);
if (v.length < l)
throw new Error(`not enough data to read on TLV ${t}`);
result[t] = result[t] || [];
result[t].push(v);
}
return result;
}
// nip11.ts
var _fetch;
try {
_fetch = fetch;
} catch {
}
async function fetchRelayInformation(url) {
return await (await fetch(url.replace("ws://", "http://").replace("wss://", "https://"), {
headers: { Accept: "application/nostr+json" }
})).json();
}
// nip29.ts
function subscribeRelayGroups(pool, url, params) {
let normalized = normalizeURL(url);
let sub;
let groups = [];
fetchRelayInformation(normalized).then(async (info) => {
let rl = await pool.ensureRelay(normalized);
params.onconnect?.();
sub = rl.prepareSubscription(
[
{
kinds: [39e3],
limit: 50,
authors: [info.pubkey]
}
],
{
onevent(event) {
groups.push(parseGroup(event, normalized));
},
oneose() {
params.ongroups(groups);
sub.onevent = (event) => {
groups.push(parseGroup(event, normalized));
params.ongroups(groups);
};
}
}
);
sub.fire();
}).catch(params.onerror);
return () => sub.close();
}
async function loadGroup(pool, gr) {
let normalized = normalizeURL(gr.host);
let info = await fetchRelayInformation(normalized);
let event = await pool.get([normalized], {
kinds: [39e3],
authors: [info.pubkey],
"#d": [gr.id]
});
if (!event)
throw new Error(`group '${gr.id}' not found on ${gr.host}`);
return parseGroup(event, normalized);
}
async function loadGroupFromCode(pool, code) {
let gr = parseGroupCode(code);
if (!gr)
throw new Error(`code "${code}" does not identify a group`);
return loadGroup(pool, gr);
}
function parseGroupCode(code) {
if (code.startsWith("naddr1")) {
try {
let { data } = decode(code);
let { relays, identifier } = data;
if (!relays || relays.length === 0)
return null;
let host = relays[0];
if (host.startsWith("wss://")) {
host = host.slice(6);
}
return { host, id: identifier };
} catch (err) {
return null;
}
} else if (code.split("'").length === 2) {
let spl = code.split("'");
return { host: spl[0], id: spl[1] };
}
return null;
}
function encodeGroupReference(gr) {
if (gr.host.startsWith("https://"))
gr.host = gr.host.slice(8);
if (gr.host.startsWith("wss://"))
gr.host = gr.host.slice(6);
return `${gr.host}'${gr.id}`;
}
function parseGroup(event, relay) {
const group = { relay, pubkey: event.pubkey };
for (let i = 0; i < event.tags.length; i++) {

@@ -34,22 +248,22 @@ const tag = event.tags[i];

case "d":
chan.id = tag[1] || "";
group.id = tag[1] || "";
break;
case "name":
chan.name = tag[1] || "";
group.name = tag[1] || "";
break;
case "about":
chan.about = tag[1] || "";
group.about = tag[1] || "";
break;
case "picture":
chan.picture = tag[1] || "";
group.picture = tag[1] || "";
break;
case "open":
chan.open = true;
group.open = true;
break;
case "public":
chan.public = true;
group.public = true;
break;
}
}
return chan;
return group;
}

@@ -56,0 +270,0 @@ function parseMembers(event) {

@@ -69,2 +69,4 @@ "use strict";

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -71,0 +73,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -71,2 +71,4 @@ "use strict";

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -73,0 +75,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -36,2 +36,4 @@ "use strict";

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -38,0 +40,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -66,2 +66,4 @@ // kinds.ts

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -68,0 +70,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -66,2 +66,4 @@ // kinds.ts

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -68,0 +70,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -59,2 +59,4 @@ var __defProp = Object.defineProperty;

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -241,2 +243,3 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

FileMetadata: () => FileMetadata,
FileServerPreference: () => FileServerPreference,
Followsets: () => Followsets,

@@ -355,2 +358,3 @@ GenericRepost: () => GenericRepost,

var UserEmojiList = 10030;
var FileServerPreference = 10096;
var NWCWalletInfo = 13194;

@@ -357,0 +361,0 @@ var LightningPubRPC = 21e3;

@@ -66,2 +66,3 @@ // kinds.ts

var UserEmojiList = 10030;
var FileServerPreference = 10096;
var NWCWalletInfo = 13194;

@@ -130,2 +131,3 @@ var LightningPubRPC = 21e3;

FileMetadata,
FileServerPreference,
Followsets,

@@ -132,0 +134,0 @@ GenericRepost,

@@ -0,4 +1,211 @@

// nip19.ts
import { bytesToHex, concatBytes, hexToBytes } from "@noble/hashes/utils";
import { bech32 } from "@scure/base";
// utils.ts
var utf8Decoder = new TextDecoder("utf-8");
var utf8Encoder = new TextEncoder();
function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);
p.pathname = p.pathname.replace(/\/+/g, "/");
if (p.pathname.endsWith("/"))
p.pathname = p.pathname.slice(0, -1);
if (p.port === "80" && p.protocol === "ws:" || p.port === "443" && p.protocol === "wss:")
p.port = "";
p.searchParams.sort();
p.hash = "";
return p.toString();
}
// nip19.ts
var Bech32MaxSize = 5e3;
function decode(nip19) {
let { prefix, words } = bech32.decode(nip19, Bech32MaxSize);
let data = new Uint8Array(bech32.fromWords(words));
switch (prefix) {
case "nprofile": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for nprofile");
if (tlv[0][0].length !== 32)
throw new Error("TLV 0 should be 32 bytes");
return {
type: "nprofile",
data: {
pubkey: bytesToHex(tlv[0][0]),
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
}
};
}
case "nevent": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for nevent");
if (tlv[0][0].length !== 32)
throw new Error("TLV 0 should be 32 bytes");
if (tlv[2] && tlv[2][0].length !== 32)
throw new Error("TLV 2 should be 32 bytes");
if (tlv[3] && tlv[3][0].length !== 4)
throw new Error("TLV 3 should be 4 bytes");
return {
type: "nevent",
data: {
id: bytesToHex(tlv[0][0]),
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : [],
author: tlv[2]?.[0] ? bytesToHex(tlv[2][0]) : void 0,
kind: tlv[3]?.[0] ? parseInt(bytesToHex(tlv[3][0]), 16) : void 0
}
};
}
case "naddr": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for naddr");
if (!tlv[2]?.[0])
throw new Error("missing TLV 2 for naddr");
if (tlv[2][0].length !== 32)
throw new Error("TLV 2 should be 32 bytes");
if (!tlv[3]?.[0])
throw new Error("missing TLV 3 for naddr");
if (tlv[3][0].length !== 4)
throw new Error("TLV 3 should be 4 bytes");
return {
type: "naddr",
data: {
identifier: utf8Decoder.decode(tlv[0][0]),
pubkey: bytesToHex(tlv[2][0]),
kind: parseInt(bytesToHex(tlv[3][0]), 16),
relays: tlv[1] ? tlv[1].map((d) => utf8Decoder.decode(d)) : []
}
};
}
case "nrelay": {
let tlv = parseTLV(data);
if (!tlv[0]?.[0])
throw new Error("missing TLV 0 for nrelay");
return {
type: "nrelay",
data: utf8Decoder.decode(tlv[0][0])
};
}
case "nsec":
return { type: prefix, data };
case "npub":
case "note":
return { type: prefix, data: bytesToHex(data) };
default:
throw new Error(`unknown prefix ${prefix}`);
}
}
function parseTLV(data) {
let result = {};
let rest = data;
while (rest.length > 0) {
let t = rest[0];
let l = rest[1];
let v = rest.slice(2, 2 + l);
rest = rest.slice(2 + l);
if (v.length < l)
throw new Error(`not enough data to read on TLV ${t}`);
result[t] = result[t] || [];
result[t].push(v);
}
return result;
}
// nip11.ts
var _fetch;
try {
_fetch = fetch;
} catch {
}
async function fetchRelayInformation(url) {
return await (await fetch(url.replace("ws://", "http://").replace("wss://", "https://"), {
headers: { Accept: "application/nostr+json" }
})).json();
}
// nip29.ts
function parseGroup(event) {
const chan = {};
function subscribeRelayGroups(pool, url, params) {
let normalized = normalizeURL(url);
let sub;
let groups = [];
fetchRelayInformation(normalized).then(async (info) => {
let rl = await pool.ensureRelay(normalized);
params.onconnect?.();
sub = rl.prepareSubscription(
[
{
kinds: [39e3],
limit: 50,
authors: [info.pubkey]
}
],
{
onevent(event) {
groups.push(parseGroup(event, normalized));
},
oneose() {
params.ongroups(groups);
sub.onevent = (event) => {
groups.push(parseGroup(event, normalized));
params.ongroups(groups);
};
}
}
);
sub.fire();
}).catch(params.onerror);
return () => sub.close();
}
async function loadGroup(pool, gr) {
let normalized = normalizeURL(gr.host);
let info = await fetchRelayInformation(normalized);
let event = await pool.get([normalized], {
kinds: [39e3],
authors: [info.pubkey],
"#d": [gr.id]
});
if (!event)
throw new Error(`group '${gr.id}' not found on ${gr.host}`);
return parseGroup(event, normalized);
}
async function loadGroupFromCode(pool, code) {
let gr = parseGroupCode(code);
if (!gr)
throw new Error(`code "${code}" does not identify a group`);
return loadGroup(pool, gr);
}
function parseGroupCode(code) {
if (code.startsWith("naddr1")) {
try {
let { data } = decode(code);
let { relays, identifier } = data;
if (!relays || relays.length === 0)
return null;
let host = relays[0];
if (host.startsWith("wss://")) {
host = host.slice(6);
}
return { host, id: identifier };
} catch (err) {
return null;
}
} else if (code.split("'").length === 2) {
let spl = code.split("'");
return { host: spl[0], id: spl[1] };
}
return null;
}
function encodeGroupReference(gr) {
if (gr.host.startsWith("https://"))
gr.host = gr.host.slice(8);
if (gr.host.startsWith("wss://"))
gr.host = gr.host.slice(6);
return `${gr.host}'${gr.id}`;
}
function parseGroup(event, relay) {
const group = { relay, pubkey: event.pubkey };
for (let i = 0; i < event.tags.length; i++) {

@@ -8,22 +215,22 @@ const tag = event.tags[i];

case "d":
chan.id = tag[1] || "";
group.id = tag[1] || "";
break;
case "name":
chan.name = tag[1] || "";
group.name = tag[1] || "";
break;
case "about":
chan.about = tag[1] || "";
group.about = tag[1] || "";
break;
case "picture":
chan.picture = tag[1] || "";
group.picture = tag[1] || "";
break;
case "open":
chan.open = true;
group.open = true;
break;
case "public":
chan.public = true;
group.public = true;
break;
}
}
return chan;
return group;
}

@@ -50,4 +257,9 @@ function parseMembers(event) {

export {
encodeGroupReference,
loadGroup,
loadGroupFromCode,
parseGroup,
parseMembers
parseGroupCode,
parseMembers,
subscribeRelayGroups
};

@@ -42,2 +42,4 @@ // pure.ts

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -44,0 +46,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -42,2 +42,4 @@ // pure.ts

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -44,0 +46,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

@@ -5,2 +5,4 @@ // utils.ts

function normalizeURL(url) {
if (url.indexOf("://") === -1)
url = "wss://" + url;
let p = new URL(url);

@@ -7,0 +9,0 @@ p.pathname = p.pathname.replace(/\/+/g, "/");

1

lib/types/abstract-relay.d.ts

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

/// <reference types="bun-types" />
import type { Event, EventTemplate, VerifiedEvent, Nostr } from './core.ts';

@@ -3,0 +2,0 @@ import { type Filter } from './filter.ts';

@@ -54,2 +54,3 @@ /** Events are **regular**, which means they're all expected to be stored by relays. */

export declare const UserEmojiList = 10030;
export declare const FileServerPreference = 10096;
export declare const NWCWalletInfo = 13194;

@@ -56,0 +57,0 @@ export declare const LightningPubRPC = 21000;

@@ -1,12 +0,27 @@

import type { Event } from './pure';
import { AbstractSimplePool } from './abstract-pool';
import type { Event } from './core';
export declare function subscribeRelayGroups(pool: AbstractSimplePool, url: string, params: {
ongroups: (_: Group[]) => void;
onerror: (_: Error) => void;
onconnect?: () => void;
}): () => void;
export declare function loadGroup(pool: AbstractSimplePool, gr: GroupReference): Promise<Group>;
export declare function loadGroupFromCode(pool: AbstractSimplePool, code: string): Promise<Group>;
export type GroupReference = {
id: string;
host: string;
};
export declare function parseGroupCode(code: string): null | GroupReference;
export declare function encodeGroupReference(gr: GroupReference): string;
export type Group = {
id: string;
relay: string;
pubkey: string;
name?: string;
picture?: string;
about?: string;
relay?: string;
public?: boolean;
open?: boolean;
};
export declare function parseGroup(event: Event): Group;
export declare function parseGroup(event: Event, relay: string): Group;
export type Member = {

@@ -13,0 +28,0 @@ pubkey: string;

import { type Event } from './pure.ts';
export declare function buildEvent(params: Partial<Event>): Event;
export declare function newMockRelay(): {
export declare class MockRelay {
private _server;
url: string;
authors: string[];
ids: string[];
};
secretKeys: Uint8Array[];
preloadedEvents: Event[];
constructor(url?: string | undefined);
get authors(): string[];
get ids(): string[];
}

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

/// <reference types="bun-types" />
import type { Event } from './core.ts';

@@ -3,0 +2,0 @@ export declare const utf8Decoder: TextDecoder;

{
"type": "module",
"name": "nostr-tools",
"version": "2.1.4",
"version": "2.1.5",
"description": "Tools for making a Nostr client.",

@@ -216,2 +216,3 @@ "repository": {

"mock-socket": "^9.3.1",
"msw": "^2.1.4",
"node-fetch": "^2.6.9",

@@ -223,4 +224,4 @@ "prettier": "^3.0.3",

"scripts": {
"prepublish": "just build && just emit-types"
"prepublish": "just build"
}
}

@@ -277,1 +277,5 @@ # ![](https://img.shields.io/github/actions/workflow/status/nbd-wtf/nostr-tools/test.yml) nostr-tools

This is free and unencumbered software released into the public domain. By submitting patches to this project, you agree to dedicate any and all copyright interest in this software to the public domain.
## Contributing to this repository
Use NIP-34 to send your patches to `naddr1qq9kummnw3ez6ar0dak8xqg5waehxw309aex2mrp0yhxummnw3ezucn8qyt8wumn8ghj7un9d3shjtnwdaehgu3wvfskueqpzemhxue69uhhyetvv9ujuurjd9kkzmpwdejhgq3q80cvv07tjdrrgpa0j7j7tmnyl2yr6yr7l8j4s3evf6u64th6gkwsxpqqqpmejdv00jq`.

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

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