Socket
Socket
Sign inDemoInstall

external-editor

Package Overview
Dependencies
5
Maintainers
1
Versions
18
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

Comparing version 2.2.0 to 3.0.0

main/errors/CreateFileError.d.ts

2

example_async.js

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

var ExternalEditor = require('./main');
var ExternalEditor = require('./main').ExternalEditor;
var readline = require('readline');

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

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

var ExternalEditor = require('./main');
var ExternalEditor = require('./main').ExternalEditor;
var readline = require('readline');

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

@@ -1,29 +0,36 @@

// Generated by CoffeeScript 1.12.7
/*
ExternalEditor
Kevin Gravier <kevin@mrkmg.com>
MIT
"use strict";
/***
* Node External Editor
*
* Kevin Gravier <kevin@mrkmg.com>
* MIT 2018
*/
(function() {
var CreateFileError,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
CreateFileError = (function(superClass) {
extend(CreateFileError, superClass);
CreateFileError.prototype.message = 'Failed to create temporary file for editor';
function CreateFileError(original_error) {
this.original_error = original_error;
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var CreateFileError = /** @class */ (function (_super) {
__extends(CreateFileError, _super);
function CreateFileError(originalError) {
var _newTarget = this.constructor;
var _this = _super.call(this, "Failed to create temporary file for editor") || this;
_this.originalError = originalError;
var proto = _newTarget.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(_this, proto);
}
else {
_this.__proto__ = _newTarget.prototype;
}
return _this;
}
return CreateFileError;
})(Error);
module.exports = CreateFileError;
}).call(this);
}(Error));
exports.CreateFileError = CreateFileError;

@@ -1,29 +0,36 @@

// Generated by CoffeeScript 1.12.7
/*
ExternalEditor
Kevin Gravier <kevin@mrkmg.com>
MIT
"use strict";
/***
* Node External Editor
*
* Kevin Gravier <kevin@mrkmg.com>
* MIT 2018
*/
(function() {
var LaunchEditorError,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
LaunchEditorError = (function(superClass) {
extend(LaunchEditorError, superClass);
LaunchEditorError.prototype.message = 'Failed launch editor';
function LaunchEditorError(original_error) {
this.original_error = original_error;
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var LaunchEditorError = /** @class */ (function (_super) {
__extends(LaunchEditorError, _super);
function LaunchEditorError(originalError) {
var _newTarget = this.constructor;
var _this = _super.call(this, "Failed launch editor") || this;
_this.originalError = originalError;
var proto = _newTarget.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(_this, proto);
}
else {
_this.__proto__ = _newTarget.prototype;
}
return _this;
}
return LaunchEditorError;
})(Error);
module.exports = LaunchEditorError;
}).call(this);
}(Error));
exports.LaunchEditorError = LaunchEditorError;

@@ -1,29 +0,36 @@

// Generated by CoffeeScript 1.12.7
/*
ExternalEditor
Kevin Gravier <kevin@mrkmg.com>
MIT
"use strict";
/***
* Node External Editor
*
* Kevin Gravier <kevin@mrkmg.com>
* MIT 2018
*/
(function() {
var ReadFileError,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
ReadFileError = (function(superClass) {
extend(ReadFileError, superClass);
ReadFileError.prototype.message = 'Failed to read temporary file';
function ReadFileError(original_error) {
this.original_error = original_error;
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var ReadFileError = /** @class */ (function (_super) {
__extends(ReadFileError, _super);
function ReadFileError(originalError) {
var _newTarget = this.constructor;
var _this = _super.call(this, "Failed to read temporary file") || this;
_this.originalError = originalError;
var proto = _newTarget.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(_this, proto);
}
else {
_this.__proto__ = _newTarget.prototype;
}
return _this;
}
return ReadFileError;
})(Error);
module.exports = ReadFileError;
}).call(this);
}(Error));
exports.ReadFileError = ReadFileError;

@@ -1,29 +0,36 @@

// Generated by CoffeeScript 1.12.7
/*
ExternalEditor
Kevin Gravier <kevin@mrkmg.com>
MIT
"use strict";
/***
* Node External Editor
*
* Kevin Gravier <kevin@mrkmg.com>
* MIT 2018
*/
(function() {
var RemoveFileError,
extend = function(child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
hasProp = {}.hasOwnProperty;
RemoveFileError = (function(superClass) {
extend(RemoveFileError, superClass);
RemoveFileError.prototype.message = 'Failed to cleanup temporary file';
function RemoveFileError(original_error) {
this.original_error = original_error;
var __extends = (this && this.__extends) || (function () {
var extendStatics = Object.setPrototypeOf ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
return function (d, b) {
extendStatics(d, b);
function __() { this.constructor = d; }
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
var RemoveFileError = /** @class */ (function (_super) {
__extends(RemoveFileError, _super);
function RemoveFileError(originalError) {
var _newTarget = this.constructor;
var _this = _super.call(this, "Failed to cleanup temporary file") || this;
_this.originalError = originalError;
var proto = _newTarget.prototype;
if (Object.setPrototypeOf) {
Object.setPrototypeOf(_this, proto);
}
else {
_this.__proto__ = _newTarget.prototype;
}
return _this;
}
return RemoveFileError;
})(Error);
module.exports = RemoveFileError;
}).call(this);
}(Error));
exports.RemoveFileError = RemoveFileError;

@@ -1,229 +0,163 @@

// Generated by CoffeeScript 1.12.7
/*
ExternalEditor
Kevin Gravier <kevin@mrkmg.com>
MIT
"use strict";
/***
* Node External Editor
*
* Kevin Gravier <kevin@mrkmg.com>
* MIT 2018
*/
(function() {
var ChatDet, CreateFileError, ExternalEditor, FS, IConvLite, LaunchEditorError, ReadFileError, RemoveFileError, Spawn, SpawnSync, Temp,
bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
FS = require('fs');
Temp = require('tmp');
SpawnSync = require('child_process').spawnSync;
Spawn = require('child_process').spawn;
IConvLite = require('iconv-lite');
ChatDet = require('chardet');
CreateFileError = require('./errors/CreateFileError');
ReadFileError = require('./errors/ReadFileError');
RemoveFileError = require('./errors/RemoveFileError');
LaunchEditorError = require('./errors/LaunchEditorError');
ExternalEditor = (function() {
ExternalEditor.edit = function(text) {
var editor;
if (text == null) {
text = '';
}
editor = new ExternalEditor(text);
editor.run();
editor.cleanup();
return editor.text;
};
ExternalEditor.editAsync = function(text, callback) {
var editor;
if (text == null) {
text = '';
}
editor = new ExternalEditor(text);
return editor.runAsync(function(error_run, text) {
var error_cleanup;
if (!error_run) {
try {
editor.cleanup();
if (typeof callback === 'function') {
return setImmediate(callback, null, text);
Object.defineProperty(exports, "__esModule", { value: true });
var chardet_1 = require("chardet");
var child_process_1 = require("child_process");
var fs_1 = require("fs");
var iconv_lite_1 = require("iconv-lite");
var tmp_1 = require("tmp");
var CreateFileError_1 = require("./errors/CreateFileError");
exports.CreateFileError = CreateFileError_1.CreateFileError;
var LaunchEditorError_1 = require("./errors/LaunchEditorError");
exports.LaunchEditorError = LaunchEditorError_1.LaunchEditorError;
var ReadFileError_1 = require("./errors/ReadFileError");
exports.ReadFileError = ReadFileError_1.ReadFileError;
var RemoveFileError_1 = require("./errors/RemoveFileError");
exports.RemoveFileError = RemoveFileError_1.RemoveFileError;
function edit(text) {
if (text === void 0) { text = ""; }
var editor = new ExternalEditor(text);
editor.run();
editor.cleanup();
return editor.text;
}
exports.edit = edit;
function editAsync(text, callback) {
if (text === void 0) { text = ""; }
var editor = new ExternalEditor(text);
editor.runAsync(function (err, result) {
if (err) {
setImmediate(callback, err, null);
}
else {
try {
editor.cleanup();
setImmediate(callback, null, result);
}
} catch (error) {
error_cleanup = error;
if (typeof callback === 'function') {
return setImmediate(callback, error_cleanup, null);
catch (cleanupError) {
setImmediate(callback, cleanupError, null);
}
}
} else {
if (typeof callback === 'function') {
return setImmediate(callback, error_run, null);
}
}
});
};
ExternalEditor.CreateFileError = CreateFileError;
ExternalEditor.ReadFileError = ReadFileError;
ExternalEditor.RemoveFileError = RemoveFileError;
ExternalEditor.LaunchEditorError = LaunchEditorError;
ExternalEditor.prototype.text = '';
ExternalEditor.prototype.temp_file = void 0;
ExternalEditor.prototype.editor = {
bin: void 0,
args: []
};
ExternalEditor.prototype.last_exit_status = void 0;
function ExternalEditor(text1) {
this.text = text1 != null ? text1 : '';
this.launchEditorAsync = bind(this.launchEditorAsync, this);
this.launchEditor = bind(this.launchEditor, this);
this.removeTemporaryFile = bind(this.removeTemporaryFile, this);
this.readTemporaryFile = bind(this.readTemporaryFile, this);
this.createTemporaryFile = bind(this.createTemporaryFile, this);
this.determineEditor = bind(this.determineEditor, this);
this.cleanup = bind(this.cleanup, this);
this.runAsync = bind(this.runAsync, this);
this.run = bind(this.run, this);
this.determineEditor();
this.createTemporaryFile();
});
}
exports.editAsync = editAsync;
var ExternalEditor = /** @class */ (function () {
function ExternalEditor(text) {
if (text === void 0) { text = ""; }
this.text = "";
this.text = text;
this.determineEditor();
this.createTemporaryFile();
}
ExternalEditor.prototype.run = function() {
this.launchEditor();
return this.readTemporaryFile();
Object.defineProperty(ExternalEditor.prototype, "temp_file", {
get: function () {
console.log("DEPRECATED: temp_file. Use tempFile moving forward.");
return this.tempFile;
},
enumerable: true,
configurable: true
});
Object.defineProperty(ExternalEditor.prototype, "last_exit_status", {
get: function () {
console.log("DEPRECATED: last_exit_status. Use lastExitStatus moving forward.");
return this.lastExitStatus;
},
enumerable: true,
configurable: true
});
ExternalEditor.prototype.run = function () {
this.launchEditor();
this.readTemporaryFile();
return this.text;
};
ExternalEditor.prototype.runAsync = function(callback) {
var error_launch;
try {
return this.launchEditorAsync((function(_this) {
return function() {
var error_read;
try {
_this.readTemporaryFile();
if (typeof callback === 'function') {
return setImmediate(callback, null, _this.text);
}
} catch (error) {
error_read = error;
if (typeof callback === 'function') {
return setImmediate(callback, error_read, null);
}
}
};
})(this));
} catch (error) {
error_launch = error;
if (typeof callback === 'function') {
return setImmediate(callback, error_launch, null);
ExternalEditor.prototype.runAsync = function (callback) {
var _this = this;
try {
this.launchEditorAsync(function () {
try {
_this.readTemporaryFile();
setImmediate(callback, null, _this.text);
}
catch (readError) {
setImmediate(callback, readError, null);
}
});
}
}
catch (launchError) {
setImmediate(callback, launchError, null);
}
};
ExternalEditor.prototype.cleanup = function() {
return this.removeTemporaryFile();
ExternalEditor.prototype.cleanup = function () {
this.removeTemporaryFile();
};
ExternalEditor.prototype.determineEditor = function() {
var args, ed, editor;
ed = /^win/.test(process.platform) ? 'notepad' : 'vim';
editor = process.env.VISUAL || process.env.EDITOR || ed;
args = editor.split(/\s+/);
this.editor.bin = args.shift();
return this.editor.args = args;
ExternalEditor.prototype.determineEditor = function () {
var editor = process.env.VISUAL ? process.env.VISUAL :
process.env.EDITOR ? process.env.EDITOR :
/^win/.test(process.platform) ? "notepad" :
"vim";
var editorOpts = editor.split(/\s+/);
var bin = editorOpts.shift();
this.editor = { args: editorOpts, bin: bin };
};
ExternalEditor.prototype.createTemporaryFile = function() {
var e;
try {
this.temp_file = Temp.tmpNameSync({});
return FS.writeFileSync(this.temp_file, this.text, {
encoding: 'utf8'
});
} catch (error) {
e = error;
throw new CreateFileError(e);
}
ExternalEditor.prototype.createTemporaryFile = function () {
try {
this.tempFile = tmp_1.tmpNameSync({});
fs_1.writeFileSync(this.tempFile, this.text, { encoding: "utf8" });
}
catch (createFileError) {
throw new CreateFileError_1.CreateFileError(createFileError);
}
};
ExternalEditor.prototype.readTemporaryFile = function() {
var buffer, e, encoding;
try {
buffer = FS.readFileSync(this.temp_file);
if (!buffer.length) {
return this.text = '';
ExternalEditor.prototype.readTemporaryFile = function () {
try {
var tempFileBuffer = fs_1.readFileSync(this.tempFile);
if (tempFileBuffer.length === 0) {
this.text = "";
}
else {
var encoding = chardet_1.detect(tempFileBuffer).toString();
this.text = iconv_lite_1.decode(tempFileBuffer, encoding);
}
}
encoding = ChatDet.detect(buffer);
return this.text = IConvLite.decode(buffer, encoding);
} catch (error) {
e = error;
throw new ReadFileError(e);
}
catch (readFileError) {
throw new ReadFileError_1.ReadFileError(readFileError);
}
};
ExternalEditor.prototype.removeTemporaryFile = function() {
var e;
try {
return FS.unlinkSync(this.temp_file);
} catch (error) {
e = error;
throw new RemoveFileError(e);
}
ExternalEditor.prototype.removeTemporaryFile = function () {
try {
fs_1.unlinkSync(this.tempFile);
}
catch (removeFileError) {
throw new RemoveFileError_1.RemoveFileError(removeFileError);
}
};
ExternalEditor.prototype.launchEditor = function() {
var e, run;
try {
run = SpawnSync(this.editor.bin, this.editor.args.concat([this.temp_file]), {
stdio: 'inherit'
});
return this.last_exit_status = run.status;
} catch (error) {
e = error;
throw new LaunchEditorError(e);
}
ExternalEditor.prototype.launchEditor = function () {
try {
var editorProcess = child_process_1.spawnSync(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
this.lastExitStatus = editorProcess.status;
}
catch (launchError) {
throw new LaunchEditorError_1.LaunchEditorError(launchError);
}
};
ExternalEditor.prototype.launchEditorAsync = function(callback) {
var child_process, e;
try {
child_process = Spawn(this.editor.bin, this.editor.args.concat([this.temp_file]), {
stdio: 'inherit'
});
return child_process.on('exit', (function(_this) {
return function(code) {
_this.last_exit_status = code;
if (typeof callback === 'function') {
return callback();
}
};
})(this));
} catch (error) {
e = error;
throw new LaunchEditorError(e);
}
ExternalEditor.prototype.launchEditorAsync = function (callback) {
var _this = this;
try {
var editorProcess = child_process_1.spawn(this.editor.bin, this.editor.args.concat([this.tempFile]), { stdio: "inherit" });
editorProcess.on("exit", function (code) {
_this.lastExitStatus = code;
setImmediate(callback);
});
}
catch (launchError) {
throw new LaunchEditorError_1.LaunchEditorError(launchError);
}
};
return ExternalEditor;
})();
module.exports = ExternalEditor;
}).call(this);
}());
exports.ExternalEditor = ExternalEditor;
{
"name": "external-editor",
"version": "2.2.0",
"version": "3.0.0",
"description": "Edit a string with the users preferred text editor using $VISUAL or $ENVIRONMENT",
"main": "main/index.js",
"types": "main/index.d.ts",
"scripts": {
"test": "npm run lint && npm run unit",
"unit": "mocha --recursive --compilers coffee:coffee-script/register --timeout 10000 ./test/spec",
"compile": "coffee --compile --output main/ src/",
"lint": "coffeelint -f .coffeelint.json src"
"unit": "mocha --recursive --require ts-node/register --timeout 10000 ./test/spec 'test/spec/**/*.ts'",
"compile": "tsc -p tsconfig.json",
"lint": "tslint './src/**/*.ts' './test/**/*.ts'"
},

@@ -29,14 +30,21 @@ "repository": {

"dependencies": {
"chardet": "^0.4.0",
"iconv-lite": "^0.4.17",
"chardet": "^0.5.0",
"iconv-lite": "^0.4.22",
"tmp": "^0.0.33"
},
"engines": {
"node": ">=0.12"
"node": ">=4"
},
"devDependencies": {
"@types/chai": "^4.1.3",
"@types/chardet": "^0.5.0",
"@types/mocha": "^5.2.0",
"@types/node": "4.0.*",
"@types/tmp": "0.0.33",
"chai": "^4.0.0",
"coffee-script": "^1.10.0",
"coffeelint": "^1.14.2",
"mocha": "^3.2.0"
"es6-shim": "^0.35.3",
"mocha": "^5.1.1",
"ts-node": "^6.0.3",
"tslint": "^5.10.0",
"typescript": "^2.8.3"
},

@@ -47,3 +55,10 @@ "files": [

"example_async.js"
]
],
"config": {
"ndt": {
"versions": [
"major"
]
}
}
}

@@ -10,5 +10,5 @@ # External Editor

Version: 2.2.0
Version: 3.0.0
As of version 2.0.0, node 0.10 is no longer support. Minimum node version is now 0.12.
As of version 3.0.0, the minimum version of node supported is 4.

@@ -23,4 +23,4 @@ ## Install

var ExternalEditor = require('external-editor')
var data = ExternalEditor.edit('\n\n# Please write your text above');
import {edit} from "external-editor";
const data = edit('\n\n# Please write your text above');
console.log(data);

@@ -30,7 +30,7 @@

var ExternalEditor = require('external-editor');
import {ExternalEditor, CreateFileError, ReadFileError, RemoveFileError} from "external-editor"
try {
var editor = new ExternalEditor();
var text = editor.run() // the text is also available in editor.text
const editor = new ExternalEditor();
const text = editor.run() // the text is also available in editor.text

@@ -41,7 +41,7 @@ if (editor.last_exit_status !== 0) {

} catch (err) {
if (err instanceOf ExternalEditor.CreateFileError) {
if (err instanceOf CreateFileError) {
console.log('Failed to create the temporary file');
} else if (err instanceOf ExternalEditor.ReadFileError) {
} else if (err instanceOf ReadFileError) {
console.log('Failed to read the temporary file');
} else if (err instanceOf ExternalEditor.LaunchEditorError) {
} else if (err instanceOf LaunchEditorError) {
console.log('Failed to launch your editor');

@@ -59,3 +59,3 @@ } else {

} catch (err) {
if (err instanceOf ExternalEditor.RemoveFileError) {
if (err instanceOf RemoveFileError) {
console.log('Failed to remove the temporary file');

@@ -69,3 +69,3 @@ } else {

#### API
**Static Methods**
**Convenience Methods**

@@ -83,3 +83,3 @@ - `edit(text)`

**Static Properties**
**Errors**

@@ -91,3 +91,3 @@ - `CreateFileError` Error thrown if the temporary file could not be created.

**Public Methods**
**External Editor Public Methods**

@@ -107,3 +107,3 @@ - `new ExternalEditor(text)`

**Public Properties**
**External Editor Public Properties**

@@ -113,9 +113,9 @@ - `text` (string) *readonly* The text in the temporary file.

- `editor.args` (array) Default arguments for the bin
- `temp_file` (string) Path to temporary file. Can be changed, but be careful as the temporary file probably already
- `tempFile` (string) Path to temporary file. Can be changed, but be careful as the temporary file probably already
exists and would need be removed manually.
- `last_exit_status` (number) The last exit code emitted from the editor.
- `lastExitStatus` (number) The last exit code emitted from the editor.
## Errors
All errors have a simple message explaining what went wrong. They all also have an `original_error` property containing
All errors have a simple message explaining what went wrong. They all also have an `originalError` property containing
the original error thrown for debugging purposes.

@@ -133,3 +133,3 @@

listening to the stdin or you write to stdout, you will most likely have problem, so make sure to remove any other
listeners on stdin, stdout, or stdin.
listeners on stdin, stdout, or stderr.

@@ -139,2 +139,11 @@ ## Demo

[![asciicast](https://asciinema.org/a/a1qh9lypbe65mj0ivfuoslz2s.png)](https://asciinema.org/a/a1qh9lypbe65mj0ivfuoslz2s)
## Breaking Changes from v2 to v3
- NodeJS 0.12 support dropped.
- Switched to named imports.
- All "snake_cased" variables and properties are now "camelCased".
- `ExternalEditor.temp_file` is now `ExternalEditor.tempFile`.
- `ExternalEditor.last_exit_status` is now `ExternalEditor.lastExitStatus`.
- `Error.original_error` is now `Error.originalError`.

@@ -145,3 +154,3 @@ ## License

Copyright (c) 2016 Kevin Gravier
Copyright (c) 2016-2018 Kevin Gravier

@@ -148,0 +157,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc