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

@krlwlfrt/dml

Package Overview
Dependencies
Maintainers
0
Versions
15
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@krlwlfrt/dml - npm Package Compare versions

Comparing version 1.0.0 to 1.2.0

2

lib/index.d.ts

@@ -8,3 +8,5 @@ export interface Module {

export declare function isRunningInTSNode(): boolean;
export declare function isRunningInDeno(): boolean;
export declare function isRunningInTypeScriptRuntime(): boolean;
export declare function loadModule(file: string): Promise<Module>;
export declare function loadModules(directory: string, recursive?: boolean): Promise<Module[]>;

54

lib/index.js

@@ -35,6 +35,12 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.loadModules = exports.loadModule = exports.isRunningInTSNode = exports.isTypeScriptFile = exports.isJavaScriptFile = void 0;
const fs_1 = require("fs");
const promises_1 = require("fs/promises");
const path_1 = require("path");
exports.isJavaScriptFile = isJavaScriptFile;
exports.isTypeScriptFile = isTypeScriptFile;
exports.isRunningInTSNode = isRunningInTSNode;
exports.isRunningInDeno = isRunningInDeno;
exports.isRunningInTypeScriptRuntime = isRunningInTypeScriptRuntime;
exports.loadModule = loadModule;
exports.loadModules = loadModules;
const node_fs_1 = require("node:fs");
const promises_1 = require("node:fs/promises");
const node_path_1 = require("node:path");
const ts_node_1 = require("ts-node");

@@ -44,21 +50,23 @@ function isJavaScriptFile(file) {

}
exports.isJavaScriptFile = isJavaScriptFile;
function isTypeScriptFile(file) {
return /\.ts$/.test(file);
}
exports.isTypeScriptFile = isTypeScriptFile;
function isRunningInTSNode() {
return typeof process[ts_node_1.REGISTER_INSTANCE] !== 'undefined';
return 'process' in globalThis && typeof globalThis.process[ts_node_1.REGISTER_INSTANCE] !== 'undefined';
}
exports.isRunningInTSNode = isRunningInTSNode;
function isRunningInDeno() {
return typeof globalThis === 'object' && typeof globalThis.Deno === 'object';
}
function isRunningInTypeScriptRuntime() {
return isRunningInDeno() || isRunningInTSNode();
}
function loadModule(file) {
return __awaiter(this, void 0, void 0, function* () {
var _a;
if (isRunningInTSNode() && !isTypeScriptFile(file) && !isJavaScriptFile(file)) {
throw new Error(`Module ${file} can not be loaded because running in TS Node and it is not a TypeScript or a JavaScript file.`);
if (isRunningInTypeScriptRuntime() && !isTypeScriptFile(file) && !isJavaScriptFile(file)) {
throw new Error(`Module ${file} can not be loaded because running in TypeScript runtime and it is not a TypeScript or a JavaScript file.`);
}
if (!isRunningInTSNode() && !isJavaScriptFile(file)) {
if (!isRunningInTypeScriptRuntime() && !isJavaScriptFile(file)) {
throw new Error(`Module ${file} can not be loaded because it is not a JavaScript file.`);
}
if (!(0, fs_1.existsSync)(file)) {
if (!(0, node_fs_1.existsSync)(file)) {
throw new Error(`Module ${file} can not be loaded because it does not exist.`);

@@ -68,13 +76,12 @@ }

path: file,
exports: yield (_a = file.toString(), Promise.resolve().then(() => __importStar(require(_a)))),
exports: yield Promise.resolve(`${file.toString()}`).then(s => __importStar(require(s))),
};
});
}
exports.loadModule = loadModule;
function loadModules(directory, recursive = true) {
return __awaiter(this, void 0, void 0, function* () {
function loadModules(directory_1) {
return __awaiter(this, arguments, void 0, function* (directory, recursive = true) {
const files = yield (0, promises_1.readdir)(directory);
const modules = [];
for (const file of files) {
const pathToLoad = (0, path_1.join)(directory, file);
const pathToLoad = (0, node_path_1.join)(directory, file);
const stats = yield (0, promises_1.lstat)(pathToLoad);

@@ -85,8 +92,8 @@ if (stats.isDirectory() && recursive) {

}
const moduleName = (0, path_1.basename)(pathToLoad, '.js');
if (isRunningInTSNode() && isJavaScriptFile(pathToLoad) && (0, fs_1.existsSync)((0, path_1.join)((0, path_1.dirname)(pathToLoad), `${moduleName}.ts`))) {
console.info(`Skipping loading of module '${pathToLoad}' because running in TS Node and TypeScript module '${moduleName}.ts' exists in the same directory since it is assumed that the JavaScript file is the transpiled version of the TypeScript file.`);
const moduleName = (0, node_path_1.basename)(pathToLoad, '.js');
if (isRunningInTypeScriptRuntime() && isJavaScriptFile(pathToLoad) && (0, node_fs_1.existsSync)((0, node_path_1.join)((0, node_path_1.dirname)(pathToLoad), `${moduleName}.ts`))) {
console.info(`Skipping loading of module '${pathToLoad}' because running in TypeScript runtime and TypeScript module '${moduleName}.ts' exists in the same directory since it is assumed that the JavaScript file is the transpiled version of the TypeScript file.`);
continue;
}
if (isRunningInTSNode() && isTypeScriptFile(pathToLoad) || isJavaScriptFile(pathToLoad)) {
if (isRunningInTypeScriptRuntime() && isTypeScriptFile(pathToLoad) || isJavaScriptFile(pathToLoad)) {
modules.push(yield loadModule(pathToLoad));

@@ -98,3 +105,2 @@ }

}
exports.loadModules = loadModules;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFlQSwyQkFBOEI7QUFDOUIsMENBQTJDO0FBQzNDLCtCQUE2QztBQUM3QyxxQ0FBMEM7QUFxQjFDLFNBQWdCLGdCQUFnQixDQUFDLElBQVk7SUFDM0MsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFGRCw0Q0FFQztBQU9ELFNBQWdCLGdCQUFnQixDQUFDLElBQVk7SUFDM0MsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFGRCw0Q0FFQztBQUtELFNBQWdCLGlCQUFpQjtJQUMvQixPQUFPLE9BQU8sT0FBTyxDQUFDLDJCQUFpQixDQUFDLEtBQUssV0FBVyxDQUFDO0FBQzNELENBQUM7QUFGRCw4Q0FFQztBQU9ELFNBQXNCLFVBQVUsQ0FBQyxJQUFZOzs7UUFDM0MsSUFBSSxpQkFBaUIsRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUM3RSxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSxnR0FBZ0csQ0FBQyxDQUFDO1NBQ2pJO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNuRCxNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSx5REFBeUQsQ0FBQyxDQUFDO1NBQzFGO1FBRUQsSUFBSSxDQUFDLElBQUEsZUFBVSxFQUFDLElBQUksQ0FBQyxFQUFFO1lBQ3JCLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxJQUFJLCtDQUErQyxDQUFDLENBQUM7U0FDaEY7UUFFRCxPQUFPO1lBQ0wsSUFBSSxFQUFFLElBQUk7WUFDVixPQUFPLEVBQUUsWUFBYSxJQUFJLENBQUMsUUFBUSxFQUFFLDBEQUFDO1NBQ3ZDLENBQUM7SUFDSixDQUFDO0NBQUE7QUFqQkQsZ0NBaUJDO0FBUUQsU0FBc0IsV0FBVyxDQUFDLFNBQWlCLEVBQUUsU0FBUyxHQUFHLElBQUk7O1FBQ25FLE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBQSxrQkFBTyxFQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUU3QixLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRTtZQUN4QixNQUFNLFVBQVUsR0FBRyxJQUFBLFdBQUksRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDekMsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFBLGdCQUFLLEVBQUMsVUFBVSxDQUFDLENBQUM7WUFFdEMsSUFBSSxLQUFLLENBQUMsV0FBVyxFQUFFLElBQUksU0FBUyxFQUFFO2dCQUNwQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxXQUFXLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7Z0JBRTFELFNBQVM7YUFDVjtZQUVELE1BQU0sVUFBVSxHQUFHLElBQUEsZUFBUSxFQUFDLFVBQVUsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUMvQyxJQUFJLGlCQUFpQixFQUFFLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksSUFBQSxlQUFVLEVBQUMsSUFBQSxXQUFJLEVBQUMsSUFBQSxjQUFPLEVBQUMsVUFBVSxDQUFDLEVBQUUsR0FBRyxVQUFVLEtBQUssQ0FBQyxDQUFDLEVBQUU7Z0JBQ3BILE9BQU8sQ0FBQyxJQUFJLENBQUMsK0JBQStCLFVBQVUsdURBQXVELFVBQVUsa0lBQWtJLENBQUMsQ0FBQztnQkFFM1AsU0FBUzthQUNWO1lBRUQsSUFBSSxpQkFBaUIsRUFBRSxJQUFJLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxJQUFJLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxFQUFFO2dCQUN2RixPQUFPLENBQUMsSUFBSSxDQUFDLE1BQU0sVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7YUFDNUM7U0FDRjtRQUVELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FBQTtBQTNCRCxrQ0EyQkMifQ==
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXVDQSw0Q0FFQztBQU9ELDRDQUVDO0FBTUQsOENBRUM7QUFNRCwwQ0FFQztBQU1ELG9FQUVDO0FBT0QsZ0NBaUJDO0FBUUQsa0NBMkJDO0FBdEhELHFDQUFtQztBQUNuQywrQ0FBZ0Q7QUFDaEQseUNBQWtEO0FBQ2xELHFDQUEwQztBQXFCMUMsU0FBZ0IsZ0JBQWdCLENBQUMsSUFBWTtJQUMzQyxPQUFPLE9BQU8sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDNUIsQ0FBQztBQU9ELFNBQWdCLGdCQUFnQixDQUFDLElBQVk7SUFDM0MsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFNRCxTQUFnQixpQkFBaUI7SUFDL0IsT0FBTyxTQUFTLElBQUksVUFBVSxJQUFJLE9BQU8sVUFBVSxDQUFDLE9BQU8sQ0FBQywyQkFBaUIsQ0FBQyxLQUFLLFdBQVcsQ0FBQztBQUNqRyxDQUFDO0FBTUQsU0FBZ0IsZUFBZTtJQUM3QixPQUFPLE9BQU8sVUFBVSxLQUFLLFFBQVEsSUFBSSxPQUFRLFVBQWtCLENBQUMsSUFBSSxLQUFLLFFBQVEsQ0FBQztBQUN4RixDQUFDO0FBTUQsU0FBZ0IsNEJBQTRCO0lBQzFDLE9BQU8sZUFBZSxFQUFFLElBQUksaUJBQWlCLEVBQUUsQ0FBQztBQUNsRCxDQUFDO0FBT0QsU0FBc0IsVUFBVSxDQUFDLElBQVk7O1FBQzNDLElBQUksNEJBQTRCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUN6RixNQUFNLElBQUksS0FBSyxDQUFDLFVBQVUsSUFBSSwyR0FBMkcsQ0FBQyxDQUFDO1FBQzdJLENBQUM7UUFFRCxJQUFJLENBQUMsNEJBQTRCLEVBQUUsSUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDL0QsTUFBTSxJQUFJLEtBQUssQ0FBQyxVQUFVLElBQUkseURBQXlELENBQUMsQ0FBQztRQUMzRixDQUFDO1FBRUQsSUFBSSxDQUFDLElBQUEsb0JBQVUsRUFBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1lBQ3RCLE1BQU0sSUFBSSxLQUFLLENBQUMsVUFBVSxJQUFJLCtDQUErQyxDQUFDLENBQUM7UUFDakYsQ0FBQztRQUVELE9BQU87WUFDTCxJQUFJLEVBQUUsSUFBSTtZQUNWLE9BQU8sRUFBRSx5QkFBYSxJQUFJLENBQUMsUUFBUSxFQUFFLHVDQUFDO1NBQ3ZDLENBQUM7SUFDSixDQUFDO0NBQUE7QUFRRCxTQUFzQixXQUFXO3lEQUFDLFNBQWlCLEVBQUUsU0FBUyxHQUFHLElBQUk7UUFDbkUsTUFBTSxLQUFLLEdBQUcsTUFBTSxJQUFBLGtCQUFPLEVBQUMsU0FBUyxDQUFDLENBQUM7UUFDdkMsTUFBTSxPQUFPLEdBQWEsRUFBRSxDQUFDO1FBRTdCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7WUFDekIsTUFBTSxVQUFVLEdBQUcsSUFBQSxnQkFBSSxFQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN6QyxNQUFNLEtBQUssR0FBRyxNQUFNLElBQUEsZ0JBQUssRUFBQyxVQUFVLENBQUMsQ0FBQztZQUV0QyxJQUFJLEtBQUssQ0FBQyxXQUFXLEVBQUUsSUFBSSxTQUFTLEVBQUUsQ0FBQztnQkFDckMsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLE1BQU0sV0FBVyxDQUFDLFVBQVUsRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDO2dCQUUxRCxTQUFTO1lBQ1gsQ0FBQztZQUVELE1BQU0sVUFBVSxHQUFHLElBQUEsb0JBQVEsRUFBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDL0MsSUFBSSw0QkFBNEIsRUFBRSxJQUFJLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxJQUFJLElBQUEsb0JBQVUsRUFBQyxJQUFBLGdCQUFJLEVBQUMsSUFBQSxtQkFBTyxFQUFDLFVBQVUsQ0FBQyxFQUFFLEdBQUcsVUFBVSxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hJLE9BQU8sQ0FBQyxJQUFJLENBQUMsK0JBQStCLFVBQVUsa0VBQWtFLFVBQVUsa0lBQWtJLENBQUMsQ0FBQztnQkFFdFEsU0FBUztZQUNYLENBQUM7WUFFRCxJQUFJLDRCQUE0QixFQUFFLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLElBQUksZ0JBQWdCLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztnQkFDbkcsT0FBTyxDQUFDLElBQUksQ0FBQyxNQUFNLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1lBQzdDLENBQUM7UUFDSCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztDQUFBIn0=
{
"name": "@krlwlfrt/dml",
"version": "1.0.0",
"version": "1.2.0",
"description": "Dynamic module loader",

@@ -12,3 +12,3 @@ "main": "lib/index.js",

"documentation": "typedoc --out docs --readme README.md src/index.ts",
"lint": "eslint src --ext .ts",
"lint": "eslint src",
"prepublishOnly": "npm ci && npm run build && npm test",

@@ -33,16 +33,18 @@ "push": "git push && git push origin \"v$npm_package_version\"",

"devDependencies": {
"@krlwlfrt/otpc": "1.0.0",
"@eslint/js": "9.14.0",
"@krlwlfrt/otpc": "2.0.0",
"@testdeck/mocha": "0.3.3",
"@types/mocha": "10.0.1",
"@types/node": "18.14.2",
"@typescript-eslint/eslint-plugin": "5.54.0",
"@typescript-eslint/parser": "5.54.0",
"conventional-changelog-cli": "2.2.2",
"eslint": "8.35.0",
"mocha": "10.2.0",
"nyc": "15.1.0",
"rimraf": "4.1.2",
"ts-node": "10.9.1",
"typedoc": "0.23.26",
"typescript": "4.9.5"
"@types/eslint__js": "8.42.3",
"@types/mocha": "10.0.9",
"@types/node": "22.9.0",
"conventional-changelog-cli": "5.0.0",
"eslint": "9.14.0",
"eslint-plugin-jsdoc": "50.4.3",
"mocha": "10.8.2",
"nyc": "17.1.0",
"rimraf": "6.0.1",
"ts-node": "10.9.2",
"typedoc": "0.26.11",
"typescript": "5.6.3",
"typescript-eslint": "8.13.0"
},

@@ -49,0 +51,0 @@ "nyc": {

@@ -16,5 +16,5 @@ /*

import {existsSync} from 'fs';
import {lstat, readdir} from 'fs/promises';
import {basename, dirname, join} from 'path';
import {existsSync} from 'node:fs';
import {lstat, readdir} from 'node:fs/promises';
import {basename, dirname, join} from 'node:path';
import {REGISTER_INSTANCE} from 'ts-node';

@@ -38,4 +38,4 @@

* Check whether a file is a JavaScript file or not
*
* @param file File to check
* @returns Whether or not a file is a JavaScript file
*/

@@ -48,4 +48,4 @@ export function isJavaScriptFile(file: string): boolean {

* Check whether a file is a TypeScript file or not
*
* @param file File to check
* @returns Whether or not a file is a TypeScript file
*/

@@ -58,18 +58,35 @@ export function isTypeScriptFile(file: string): boolean {

* Check whether or not currently running in TS Node
* @returns Whether or not currently running in TS Node
*/
export function isRunningInTSNode(): boolean {
return typeof process[REGISTER_INSTANCE] !== 'undefined';
return 'process' in globalThis && typeof globalThis.process[REGISTER_INSTANCE] !== 'undefined';
}
/**
* Check whether or not currently running in Deno
* @returns Whether or not currently running in Deno
*/
export function isRunningInDeno(): boolean {
return typeof globalThis === 'object' && typeof (globalThis as any).Deno === 'object';
}
/**
* Check whether or not currently running in TypeScript runtime
* @returns Whether or not currently running in TypeScript runtime
*/
export function isRunningInTypeScriptRuntime(): boolean {
return isRunningInDeno() || isRunningInTSNode();
}
/**
* Load a module
*
* @param file File name of the module to load
* @returns A promise that resolves with the Module
*/
export async function loadModule(file: string): Promise<Module> {
if (isRunningInTSNode() && !isTypeScriptFile(file) && !isJavaScriptFile(file)) {
throw new Error(`Module ${file} can not be loaded because running in TS Node and it is not a TypeScript or a JavaScript file.`);
if (isRunningInTypeScriptRuntime() && !isTypeScriptFile(file) && !isJavaScriptFile(file)) {
throw new Error(`Module ${file} can not be loaded because running in TypeScript runtime and it is not a TypeScript or a JavaScript file.`);
}
if (!isRunningInTSNode() && !isJavaScriptFile(file)) {
if (!isRunningInTypeScriptRuntime() && !isJavaScriptFile(file)) {
throw new Error(`Module ${file} can not be loaded because it is not a JavaScript file.`);

@@ -90,5 +107,5 @@ }

* Load all modules in a directory
*
* @param directory Directory to load all modules from
* @param recursive Whether or not to recursively load modules from sub directories
* @returns A promise that resolves with an array of modules
*/

@@ -110,4 +127,4 @@ export async function loadModules(directory: string, recursive = true): Promise<Module[]> {

const moduleName = basename(pathToLoad, '.js');
if (isRunningInTSNode() && isJavaScriptFile(pathToLoad) && existsSync(join(dirname(pathToLoad), `${moduleName}.ts`))) {
console.info(`Skipping loading of module '${pathToLoad}' because running in TS Node and TypeScript module '${moduleName}.ts' exists in the same directory since it is assumed that the JavaScript file is the transpiled version of the TypeScript file.`);
if (isRunningInTypeScriptRuntime() && isJavaScriptFile(pathToLoad) && existsSync(join(dirname(pathToLoad), `${moduleName}.ts`))) {
console.info(`Skipping loading of module '${pathToLoad}' because running in TypeScript runtime and TypeScript module '${moduleName}.ts' exists in the same directory since it is assumed that the JavaScript file is the transpiled version of the TypeScript file.`);

@@ -117,3 +134,3 @@ continue;

if (isRunningInTSNode() && isTypeScriptFile(pathToLoad) || isJavaScriptFile(pathToLoad)) {
if (isRunningInTypeScriptRuntime() && isTypeScriptFile(pathToLoad) || isJavaScriptFile(pathToLoad)) {
modules.push(await loadModule(pathToLoad));

@@ -120,0 +137,0 @@ }

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