New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

ic4d

Package Overview
Dependencies
Maintainers
1
Versions
59
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

ic4d - npm Package Compare versions

Comparing version 1.3.0-alpha.1 to 1.3.0-alpha.2

12

dist/handler/commandHandler.d.ts
import { CoreHandler, Option } from "./coreHandler";
import { Client, Interaction, PermissionFlags } from "discord.js";
interface LoaderOptions {
loaded: string;
edited: string;
deleted: string;
skipped: string;
}
import { LoaderOptions } from "./coreHandler";
interface ReaderOptions {

@@ -46,5 +41,6 @@ testGuildId?: string;

* Register Slash Commands
* @param serverId Server Id, Makes loaded command guild wide.
* @param logAll Log when loading a command and no changes are made
* @param serverId Server Id, Makes loaded commands guild wide.
*/
registerCommands(serverId?: string): Promise<void>;
registerCommands(logAll?: boolean, serverId?: string): Promise<void>;
/**

@@ -51,0 +47,0 @@ * Handle Slash Commands

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

this.options = {
loadedNoChanges: "NAME was loaded. No changes for NAME happened.",
loaded: "NAME has been registered successfully.",

@@ -37,2 +38,3 @@ edited: "NAME has been edited.",

this.options = {
loadedNoChanges: clc.magenta.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.loadedNoChanges) || this.options.loadedNoChanges),
loaded: clc.green.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.loaded) || this.options.loaded),

@@ -53,5 +55,7 @@ edited: clc.yellow.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.edited) || this.options.edited),

* Register Slash Commands
* @param serverId Server Id, Makes loaded command guild wide.
* @param logAll Log when loading a command and no changes are made
* @param serverId Server Id, Makes loaded commands guild wide.
*/
async registerCommands(serverId) {
async registerCommands(logAll, serverId) {
logAll = logAll !== undefined ? logAll : true;
try {

@@ -64,3 +68,3 @@ const localCommands = this.getLocalCommands(this.commandPath);

!localCommand.callback) {
throw new errs.CommandLoaderError(`Command $PATH$ does not export required properties: name, description or callback`, localCommand.filePath);
throw new errs.LoaderError(`Command $PATH$ does not export required properties: name, description or callback`, localCommand.filePath);
}

@@ -98,4 +102,7 @@ const { name, description, options, filePath } = localCommand;

catch (err) {
throw new errs.CommandLoaderError(`Command $NAME$ from $PATH$:` + err, filePath, name);
throw new errs.LoaderError(`Command $NAME$ from $PATH$:` + err, filePath, name);
}
if (logAll) {
console.log(this.options.loadedNoChanges.replace("NAME", name));
}
}

@@ -105,3 +112,3 @@ }

let msg = "Loading commands failed with the error: ";
if (error instanceof errs.CommandLoaderError) {
if (error instanceof errs.LoaderError) {
throw new Error(`${clc.bold("(" + error.name + ")")} ` + msg + error.message);

@@ -173,3 +180,3 @@ }

catch (error) {
throw new errs.CommandHandlerError(`Failed to run command $NAME$ \n\n` + error, commandObject.filePath, commandObject.name);
throw new errs.HandlerError(`Failed to run command $NAME$ \n\n` + error, commandObject.filePath, commandObject.name);
}

@@ -176,0 +183,0 @@ });

import { Client, CommandInteraction, ApplicationCommandManager, GuildApplicationCommandManager } from "discord.js";
import { CommandObject } from "./commandHandler";
import { InteractionObject } from "./interactionHandler";
import { ContextMenuObject, InteractionObject } from "./interactionHandler";
export interface LoaderOptions {
/**
* What to show for context menus/commands that load in
*/
loaded: string;
/**
* What to show for context menus/commands that get edited.
*/
edited: string;
/**
* What to show for context menus/commands that get deleted.
*/
deleted: string;
/**
* What to show for context menus/commands that get skipped. (Deleted and still marked as deleted.)
*/
skipped: string;
/**
* What to show for context menus/commands that get loaded, but have no changes
*/
loadedNoChanges?: string;
}
export interface Choice {

@@ -22,6 +44,7 @@ name: string;

constructor(client: Client);
protected getInteractions(path: string, commandName?: string): InteractionObject[];
protected getInteractions(path: string, getContextMenusOnly?: boolean): (ContextMenuObject | InteractionObject)[] | ContextMenuObject[];
protected getLocalCommands(path: string, exceptions?: string[]): CommandObject[];
protected getAllFiles(directory: string, foldersOnly?: boolean): string[];
protected areCommandsDifferent(existingCommand: CommandInteraction | any, localCommand: CommandObject): boolean;
protected areContextMenusDifferent(existing: ContextMenuObject, local: ContextMenuObject): boolean;
protected getApplicationCommands(client: Client, guildId?: string): Promise<ApplicationCommandManager<import("discord.js").ApplicationCommand<{

@@ -28,0 +51,0 @@ guild: import("discord.js").GuildResolvable;

@@ -14,14 +14,4 @@ "use strict";

}
getInteractions(path, commandName) {
getInteractions(path, getContextMenusOnly) {
let interactions = [];
const containsDirectories = (path) => {
const items = fs.readdirSync(path);
let containsDirectories = [];
for (const item of items) {
const itemPath = path2.join(path, item);
const isDirectory = fs.statSync(itemPath).isDirectory();
containsDirectories.push(isDirectory);
}
return containsDirectories.reduce((acc, currentValue) => acc || currentValue, false);
};
const scanDirectory = (directory) => {

@@ -38,5 +28,20 @@ const items = fs.readdirSync(directory);

const interactionObject = require(itemPath);
if (!interactionObject.customId) {
continue;
if (getContextMenusOnly) {
if (!interactionObject.type ||
!interactionObject.name ||
typeof interactionObject.type !== "number") {
continue;
}
}
else {
if (!interactionObject.customId) {
continue;
}
interactionObject.onlyAuthor =
interactionObject.onlyAuthor == true
? true
: interactionObject.authorOnly == true
? true
: false;
}
interactionObject.filePath = itemPath;

@@ -65,9 +70,4 @@ arr.push(interactionObject);

const commandObject = require(itemPath);
if (
/*
!commandObject.name ||
!commandObject.description ||
!commandObject.callback ||
*/
commandObject.isCommand == false ||
if (!commandObject.description ||
commandObject.isCommand ||
commandObject.customId ||

@@ -151,2 +151,5 @@ exceptions.includes(commandObject.name)) {

}
areContextMenusDifferent(existing, local) {
return existing.type == local.type;
}
async getApplicationCommands(client, guildId) {

@@ -162,3 +165,3 @@ let applicationCommands;

//@ts-ignore
await applicationCommands.fetch();
await applicationCommands.fetch({ locale: "en-GB" });
return applicationCommands;

@@ -165,0 +168,0 @@ }

@@ -5,11 +5,20 @@ declare class ic4dError extends Error {

}
export declare class CommandLoaderError extends ic4dError {
export declare class LoaderError extends ic4dError {
constructor(message: string, file: string, commandName?: string);
}
export declare class CommandHandlerError extends ic4dError {
export declare class ContextLoaderError extends ic4dError {
constructor(message: string, file?: string, commandName?: string);
}
export declare class InteractionButtonError extends ic4dError {
export declare class ContextHandlerError extends ic4dError {
constructor(message: string, file?: string, commandName?: string);
}
export declare class HandlerError extends ic4dError {
constructor(message: string, file?: string, commandName?: string);
}
export declare class ButtonError extends ic4dError {
constructor(message: string, file?: string, commandName?: string);
}
export declare class SelectMenuError extends ic4dError {
constructor(message: string, file?: string, commandName?: string);
}
export {};
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.InteractionButtonError = exports.CommandHandlerError = exports.CommandLoaderError = void 0;
exports.SelectMenuError = exports.ButtonError = exports.HandlerError = exports.ContextHandlerError = exports.ContextLoaderError = exports.LoaderError = void 0;
const clc = require("cli-color");

@@ -10,3 +10,4 @@ class ic4dError extends Error {

.replace("$PATH$", clc.bold.underline(file))
.replace("$NAME$", clc.italic.bold.underline(commandName));
.replace("$NAME$", clc.italic.bold.underline(commandName))
.replace("$NAMECONTEXT$", clc.italic.bold.underline(commandName + " (context menu)"));
this.name = name;

@@ -16,20 +17,38 @@ this.fileName = file; // Additional property to store the file name

}
class CommandLoaderError extends ic4dError {
class LoaderError extends ic4dError {
constructor(message, file, commandName) {
super("LoaderError", message, file, commandName);
super("CommandLoaderError", message, file, commandName);
}
}
exports.CommandLoaderError = CommandLoaderError;
class CommandHandlerError extends ic4dError {
exports.LoaderError = LoaderError;
class ContextLoaderError extends ic4dError {
constructor(message, file, commandName) {
super("HandlerError", message, file, commandName);
super("ContextMenuLoaderError", message, file, commandName);
}
}
exports.CommandHandlerError = CommandHandlerError;
class InteractionButtonError extends ic4dError {
exports.ContextLoaderError = ContextLoaderError;
class ContextHandlerError extends ic4dError {
constructor(message, file, commandName) {
super("ContextMenuHandlerError", message, file, commandName);
}
}
exports.ContextHandlerError = ContextHandlerError;
class HandlerError extends ic4dError {
constructor(message, file, commandName) {
super("CommandHandlerError", message, file, commandName);
}
}
exports.HandlerError = HandlerError;
class ButtonError extends ic4dError {
constructor(message, file, commandName) {
super("InteractionButtonError", message, file, commandName);
}
}
exports.InteractionButtonError = InteractionButtonError;
exports.ButtonError = ButtonError;
class SelectMenuError extends ic4dError {
constructor(message, file, commandName) {
super("InteractionSelectMenuError", message, file, commandName);
}
}
exports.SelectMenuError = SelectMenuError;
//# sourceMappingURL=Errors.js.map
import { CoreHandler } from "./coreHandler";
import { Client, ButtonInteraction, AnySelectMenuInteraction } from "discord.js";
import { Client, ButtonInteraction, AnySelectMenuInteraction, MessageContextMenuCommandInteraction, UserContextMenuCommandInteraction } from "discord.js";
import { LoaderOptions } from "./coreHandler";
export interface InteractionObject {

@@ -7,6 +8,14 @@ customId?: string;

onlyAuthor?: boolean;
authorOnly?: boolean;
filePath: string;
type: string;
callback: (interaction: ButtonInteraction | AnySelectMenuInteraction, client?: Client) => void;
callback: (interaction: ButtonInteraction | AnySelectMenuInteraction | UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction, client?: Client) => void;
}
export interface ContextMenuObject {
name: string;
type: number;
deleted?: boolean;
filePath?: string;
callback: (interaction: UserContextMenuCommandInteraction | MessageContextMenuCommandInteraction, client?: Client) => void;
}
/**

@@ -20,5 +29,7 @@ * @class

buttons: Record<string, InteractionObject>;
selectMenu: Record<string, InteractionObject>;
selectMenus: Record<string, InteractionObject>;
contextMenus: Record<string, ContextMenuObject>;
};
logErrors: boolean;
options: LoaderOptions;
/**

@@ -28,5 +39,6 @@ *

* @param path Path to where the interaction objects are stored
* @param loaderOptions Loader options (for context menus)
* @param logErrors Log any occuring errors
*/
constructor(client: Client, path: string, logErrors?: boolean);
constructor(client: Client, path: string, loaderOptions?: LoaderOptions, logErrors?: boolean);
private sortInteractionObjects;

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

*/
selectMenu(authorOnlyMsg?: string): void;
selectMenus(authorOnlyMsg?: string): void;
/**
* Start listening for context menus (supports all types)
*/
contextMenus(): void;
/**
* Start listening for Select Menus, Context Menus and Buttons
* @param authorOnlyMsg Message to be displayed when a different user clicks an author only button.
*/
start(authorOnlyMsg?: string): void;
/**
* Register Context Menus
* @param logAll log even when a context menu gets loaded but doesn't change
* @param serverId Server Id, Makes loaded command guild wide.
*/
registerContextMenus(logAll?: boolean, serverId?: string): Promise<void>;
}

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

const coreHandler_1 = require("./coreHandler");
const Errors_1 = require("./Errors");
const clc = require("cli-color");
const errs = require("./Errors");
/**

@@ -16,7 +17,15 @@ * @class

* @param path Path to where the interaction objects are stored
* @param loaderOptions Loader options (for context menus)
* @param logErrors Log any occuring errors
*/
constructor(client, path, logErrors) {
constructor(client, path, loaderOptions, logErrors) {
super(client);
this.logErrors = false;
this.options = {
loadedNoChanges: "NAME was loaded. No changes for NAME happened.",
loaded: "NAME has been registered successfully.",
edited: "NAME has been edited.",
deleted: "NAME has been deleted.",
skipped: "NAME was skipped. (Command deleted or set to delete.)",
};
this.interactionsPath = path;

@@ -26,2 +35,9 @@ const interactions = this.getInteractions(this.interactionsPath);

this.logErrors = logErrors == true ? true : false;
this.options = {
loadedNoChanges: clc.magenta.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.loadedNoChanges) || this.options.loadedNoChanges),
loaded: clc.green.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.loaded) || this.options.loaded),
edited: clc.yellow.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.edited) || this.options.edited),
deleted: clc.red.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.deleted) || this.options.deleted),
skipped: clc.cyan.bold((loaderOptions === null || loaderOptions === void 0 ? void 0 : loaderOptions.skipped) || this.options.skipped),
};
}

@@ -32,22 +48,33 @@ sortInteractionObjects(interactions) {

.reduce((acc, obj) => {
acc[obj.customId] = {
callback: obj.callback,
onlyAuthor: obj.onlyAuthor,
filePath: obj.filePath,
type: obj.type,
};
return acc;
}, {});
const selectMenu = interactions
acc[obj.customId] = {
callback: obj.callback,
onlyAuthor: obj.onlyAuthor,
filePath: obj.filePath,
type: obj.type,
};
return acc;
}, {});
const selectMenus = interactions
.filter((obj) => obj.type === "selectMenu")
.reduce((acc, obj) => {
acc[obj.customId] = {
callback: obj.callback,
onlyAuthor: obj.onlyAuthor,
filePath: obj.filePath,
type: obj.type,
};
return acc;
}, {});
return { buttons, selectMenu };
acc[obj.customId] = {
callback: obj.callback,
onlyAuthor: obj.onlyAuthor,
filePath: obj.filePath,
type: obj.type,
};
return acc;
}, {});
const contextMenus = interactions
.filter((obj) => typeof obj.type === "number") // if the type property is a number, then we know damn well it's a context menu. If not you're fucking yourself over.
.reduce((acc, obj) => {
acc[obj.name] = {
name: obj.name,
type: obj.type,
filePath: obj.filePath,
callback: obj.callback,
};
return acc;
}, {});
return { buttons, selectMenus, contextMenus };
}

@@ -64,6 +91,8 @@ /**

this.client.on("interactionCreate", (interaction) => {
if (!interaction.isButton()) return;
if (!interaction.isButton())
return;
const buttonObj = this.interactions.buttons[interaction.customId];
try {
if (buttonObj == undefined) return; // for buttons that don't need this package to respond to them.
if (buttonObj == undefined)
return; // for buttons that don't need this package to respond to them.
const author = interaction.message.interaction.user.id;

@@ -79,9 +108,6 @@ const buttonClicker = interaction.member.user.id;

buttonObj.callback(interaction, this.client);
} catch (error) {
}
catch (error) {
if (this.logErrors) {
throw new Errors_1.InteractionButtonError(
"Button $NAME$ failed with the error:\n\n" + error,
buttonObj.filePath,
interaction.customId
);
throw new errs.ButtonError("Button $NAME$ failed with the error:\n\n" + error, buttonObj.filePath, interaction.customId);
}

@@ -95,3 +121,3 @@ }

*/
selectMenu(authorOnlyMsg) {
selectMenus(authorOnlyMsg) {
authorOnlyMsg =

@@ -102,11 +128,13 @@ authorOnlyMsg !== undefined

this.client.on("interactionCreate", (interaction) => {
if (!interaction.isAnySelectMenu()) return;
const selectObj =
this.interactions.selectMenu[interaction.customId];
if (!interaction.isAnySelectMenu())
return;
const selectObj = this.interactions.selectMenus[interaction.customId];
try {
if (selectObj == undefined) return; // for buttons that don't need this package to respond to them.
if (selectObj == undefined)
return; // for selects that don't need this package to respond to them.
const author = interaction.message.interaction.user.id;
const buttonClicker = interaction.member.user.id;
if (selectObj.onlyAuthor == true && author !== buttonClicker) {
interaction.followUp({
const selectMenuClicker = interaction.member.user.id;
if (selectObj.onlyAuthor == true &&
author !== selectMenuClicker) {
interaction.reply({
content: authorOnlyMsg,

@@ -118,9 +146,6 @@ ephemeral: true,

selectObj.callback(interaction, this.client);
} catch (error) {
}
catch (error) {
if (this.logErrors) {
throw new Errors_1.InteractionButtonError(
"Select Menu $NAME$ failed with the error:\n\n" + error,
selectObj.filePath,
interaction.customId
);
throw new errs.ButtonError("Select Menu $NAME$ failed with the error:\n\n" + error, selectObj.filePath, interaction.customId);
}

@@ -130,4 +155,90 @@ }

}
/**
* Start listening for context menus (supports all types)
*/
contextMenus() {
this.client.on("interactionCreate", (interaction) => {
if (!interaction.isContextMenuCommand())
return;
const contextObj = this.interactions.contextMenus[interaction.commandName];
try {
if (contextObj == undefined)
return;
contextObj.callback(interaction, this.client);
}
catch (error) {
if (this.logErrors) {
throw new errs.ContextHandlerError("Context Menu $NAME$ failed with the error:\n\n" +
error, contextObj.filePath, interaction.commandName);
}
}
});
}
/**
* Start listening for Select Menus, Context Menus and Buttons
* @param authorOnlyMsg Message to be displayed when a different user clicks an author only button.
*/
start(authorOnlyMsg) {
this.buttons(authorOnlyMsg);
this.selectMenus(authorOnlyMsg);
this.contextMenus();
}
/**
* Register Context Menus
* @param logAll log even when a context menu gets loaded but doesn't change
* @param serverId Server Id, Makes loaded command guild wide.
*/
async registerContextMenus(logAll, serverId) {
logAll = logAll !== undefined ? logAll : true;
try {
const localContexts = this.getInteractions(this.interactionsPath, true);
const applicationCommands = await this.getApplicationCommands(this.client, serverId);
for (const localContext of localContexts) {
const { name, type, filePath } = localContext;
try {
const existingContext = await applicationCommands.cache.find((con) => con.name === name);
if (existingContext) {
if (localContext.deleted) {
await applicationCommands.delete(existingContext.id);
console.log(this.options.deleted.replace("NAME", name));
continue;
}
if (this.areContextMenusDifferent(
//@ts-ignore
existingContext, localContext)) {
await applicationCommands.edit(existingContext.id, {
type,
});
console.log(this.options.edited.replace("NAME", name));
}
}
else {
if (localContext.deleted) {
console.log(this.options.skipped.replace("NAME", name));
continue;
}
await applicationCommands.create({
name,
type,
});
console.log(this.options.loaded.replace("NAME", name));
}
}
catch (err) {
throw new errs.ContextLoaderError(`Command $NAMECONTEXT$ from $PATH$:` + err, filePath, name);
}
}
}
catch (error) {
let msg = "Loading context menus failed with the error: ";
if (error instanceof errs.ContextLoaderError) {
throw new Error(`${clc.bold("(" + error.name + ")")} ` + msg + error.message);
}
else {
throw new Error(error);
}
}
}
}
exports.InteractionHandler = InteractionHandler;
//# sourceMappingURL=interactionHandler.js.map
//# sourceMappingURL=interactionHandler.js.map
{
"name": "ic4d",
"version": "1.3.0-alpha.1",
"version": "1.3.0-alpha.2",
"description": "Discord.js Interaction and Command handler 4 Dummies",

@@ -27,2 +27,6 @@ "main": "dist/index.js",

"commands",
"buttons",
"select",
"menus",
"context",
"v14",

@@ -29,0 +33,0 @@ "discord-bot",

@@ -163,2 +163,3 @@ # ic4d

{
loadedNoChanges: "NAME was loaded. No changes were made to NAME."
loaded: "NAME has been registered successfully.",

@@ -177,2 +178,3 @@ edited: "NAME has been edited.",

- `logAll`**(optional)**: Log command even if no change was performed.
- `serverId`**(optional)**: Register all commands in a specific server. if not provided it will be application wide

@@ -274,4 +276,4 @@

> - buttons
> - (soon) select menus
> - (soon) context menus
> - select menus
> - context menus
> - (soon) modals

@@ -281,3 +283,3 @@

Make sure wherever your store your interaction objects they follow the export the [interactions object](#interaction-object) with the minimum requirements being
Make sure wherever your store your interaction objects they follow the export the [interactions object](#interaction-object) with the minimum requirements being. **NOTE : This is the case for any interaction EXCEPT FOR [CONTEXT MENUS](#context-menu)**

@@ -297,2 +299,3 @@ ```js

- `path`: Path to where interactions are stored. (They can be stored in your commands folder to, as long as they meet with [interactions object](#interaction-object))
- `loaderOptions`**(optional)**: Context Menu [Loader Options](#loaderoptions)
- `logErrors`**(optional)**: Log errors that occur when interactons take place.

@@ -306,4 +309,3 @@

client,
path.join(__dirname, "commands"),
true
path.join(__dirname, "commands")
);

@@ -314,2 +316,12 @@ ```

### `start`
Start listening for all available interactions. (Context Menu, Button and Select Menu)
- `authorOnlyMsg`**(optional)**: Message to display when a interacts with another user's interaction (onlyAuthor is set to true.)
```js
interactions.start();
```
### `buttons`

@@ -325,2 +337,33 @@

### `selectMenus`
Start listening for select menu interactions.
- `authorOnlyMsg`**(optional)**: Message to display when a user click's another user's select menu (onlyAuthor is set to true.)
```js
interactions.selectMenu();
```
### `contextMenus`
Start listening for context menu interactions. (After their registered)
```js
interactions.contextMenus();
```
### `registerContextMenus`
**(asynchronous function)**
Register Context Menus. Make sure your [Context Menu object](#context-menu) looks like [this](#context-menu)
- `logAll`**(optional)**: Log context menu even if no change was performed.
- `serverId`**(optional)**: Register all commands in a specific server. if not provided it will be application wide
```js
await interactions.registerContextMenus();
```
# Command Object

@@ -395,3 +438,3 @@

## Normal
## Normal (button)

@@ -401,2 +444,3 @@ ```js

customId: "button1",
type: "button",
callback: (i) => {

@@ -408,3 +452,3 @@ // callback

## Author Only
## Author Only (selectMenu)

@@ -415,3 +459,4 @@ Not required but is handy

module.exports = {
customId: "button1",
customId: "selectMenu",
type: "selectMenu",
authorOnly: true,

@@ -437,2 +482,38 @@ callback: (i) => {

## Context Menu
This works a little differently to ones above, that's why it has it's own category lol.
```js
const { ApplicationCommandType } = require("discord.js");
module.exports = {
name: "modla",
isCommand: false,
type: ApplicationCommandType.User,
callback: (interaction) => {
const user = interaction.targetUser;
},
};
```
or
```js
const {
ContextMenuCommandBuilder,
ApplicationCommandType,
} = require("discord.js");
module.exports = {
...new ContextMenuCommandBuilder()
.setName("Balls")
.setType(ApplicationCommandType.Message),
isCommand: false,
callback: (interaction) => {
const message = interaction.targetMessage;
},
};
```
# Credits

@@ -439,0 +520,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

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