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

workers-qb

Package Overview
Dependencies
Maintainers
0
Versions
45
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

workers-qb - npm Package Compare versions

Comparing version 1.2.4 to 1.3.0

dist/index.d.mts

474

dist/index.js

@@ -1,1 +0,473 @@

"use strict";var e,t,r,s;exports.OrderTypes=void 0,(e=exports.OrderTypes||(exports.OrderTypes={})).ASC="ASC",e.DESC="DESC",exports.FetchTypes=void 0,(t=exports.FetchTypes||(exports.FetchTypes={})).ONE="ONE",t.ALL="ALL",exports.ConflictTypes=void 0,(r=exports.ConflictTypes||(exports.ConflictTypes={})).ROLLBACK="ROLLBACK",r.ABORT="ABORT",r.FAIL="FAIL",r.IGNORE="IGNORE",r.REPLACE="REPLACE",exports.JoinTypes=void 0,(s=exports.JoinTypes||(exports.JoinTypes={})).INNER="INNER",s.LEFT="LEFT",s.CROSS="CROSS";class n{isRaw=!0;content;constructor(e){this.content=e}}class o{executeMethod;query;arguments;fetchType;constructor(e,t,r,s){this.executeMethod=e,this.query=t,this.arguments=r,this.fetchType=s}async execute(){return this.executeMethod(this)}}class a{_debugger=!1;setDebugger(e){this._debugger=e}async execute(e){throw new Error("Execute method not implemented")}async batchExecute(e){throw new Error("Batch execute method not implemented")}createTable(e){return new o((e=>this.execute(e)),`CREATE TABLE ${e.ifNotExists?"IF NOT EXISTS":""} ${e.tableName}\n ( ${e.schema})`)}dropTable(e){return new o((e=>this.execute(e)),`DROP TABLE ${e.ifExists?"IF EXISTS":""} ${e.tableName}`)}fetchOne(e){return new o((e=>this.execute(e)),this._select({...e,limit:1}),"object"==typeof e.where&&!Array.isArray(e.where)&&e.where?.params?e.where?.params:void 0,exports.FetchTypes.ONE)}fetchAll(e){return new o((e=>this.execute(e)),this._select(e),"object"==typeof e.where&&!Array.isArray(e.where)&&e.where?.params?e.where?.params:void 0,exports.FetchTypes.ALL)}raw(e){return new o((e=>this.execute(e)),e.query,e.args,e.fetchType)}insert(e){let t=[];if("object"==typeof e.onConflict&&("object"==typeof e.onConflict?.where&&!Array.isArray(e.onConflict?.where)&&e.onConflict?.where?.params&&(t=t.concat(e.onConflict.where?.params)),e.onConflict.data&&(t=t.concat(this._parse_arguments(e.onConflict.data)))),Array.isArray(e.data))for(const r of e.data)t=t.concat(this._parse_arguments(r));else t=t.concat(this._parse_arguments(e.data));const r=Array.isArray(e.data)?exports.FetchTypes.ALL:exports.FetchTypes.ONE;return new o((e=>this.execute(e)),this._insert(e),t,r)}update(e){let t=this._parse_arguments(e.data);return"object"==typeof e.where&&!Array.isArray(e.where)&&e.where?.params&&(t=e.where?.params.concat(t)),new o((e=>this.execute(e)),this._update(e),t,exports.FetchTypes.ALL)}delete(e){return new o((e=>this.execute(e)),this._delete(e),"object"==typeof e.where&&!Array.isArray(e.where)&&e.where?.params?e.where?.params:void 0,exports.FetchTypes.ALL)}_parse_arguments(e){return Object.values(e).filter((e=>!(e instanceof n)))}_onConflict(e){if(e){if("object"==typeof e){Array.isArray(e.column)||(e.column=[e.column]);const t=this.update({tableName:"_REPLACE_",data:e.data,where:e.where}).query.replace(" _REPLACE_","");return` ON CONFLICT (${e.column.join(", ")}) DO ${t}`}return`OR ${e} `}return""}_insert(e){const t=[];let r;if(r=Array.isArray(e.data)?e.data:[e.data],!r||!r[0]||0===r.length)throw new Error("Insert data is undefined");const s=Object.keys(r[0]).join(", ");let o=1,a="",i="";e.onConflict&&"object"==typeof e.onConflict?(i=this._onConflict(e.onConflict),"object"==typeof e.onConflict?.where&&!Array.isArray(e.onConflict?.where)&&e.onConflict?.where?.params&&(o+=e.onConflict.where?.params.length),e.onConflict.data&&(o+=this._parse_arguments(e.onConflict.data).length)):a=this._onConflict(e.onConflict);for(const e of r){const r=[];Object.values(e).forEach((e=>{e instanceof n?r.push(e.content):(r.push(`?${o}`),o+=1)})),t.push(`(${r.join(", ")})`)}return`INSERT ${a} INTO ${e.tableName} (${s}) VALUES ${t.join(", ")}`+i+this._returning(e.returning)}_update(e){const t="object"==typeof e.where&&!Array.isArray(e.where)&&e.where?.params?Object.keys(e.where?.params).length:0,r=[];let s=1;for(const[o,a]of Object.entries(e.data))a instanceof n?r.push(`${o} = ${a.content}`):(r.push(`${o} = ?${t+s}`),s+=1);return`UPDATE ${this._onConflict(e.onConflict)}${e.tableName}\n SET ${r.join(", ")}`+this._where(e.where)+this._returning(e.returning)}_delete(e){return`DELETE\n FROM ${e.tableName}`+this._where(e.where)+this._returning(e.returning)}_select(e){return`SELECT ${this._fields(e.fields)}\n FROM ${e.tableName}`+this._join(e.join)+this._where(e.where)+this._groupBy(e.groupBy)+this._having(e.having)+this._orderBy(e.orderBy)+this._limit(e.limit)+this._offset(e.offset)}_fields(e){return e?"string"==typeof e?e:e.join(", "):"*"}_where(e){if(!e)return"";let t=e;return"object"!=typeof e||Array.isArray(e)||(t=e.conditions),"string"==typeof t?` WHERE ${t.toString()}`:t.length>0?` WHERE ${t.join(" AND ")}`:""}_join(e){if(!e)return"";Array.isArray(e)||(e=[e]);const t=[];return e.forEach((e=>{const r=e.type?`${e.type} `:"";t.push(`${r}JOIN ${"string"==typeof e.table?e.table:`(${this._select(e.table)})`}${e.alias?` AS ${e.alias}`:""} ON ${e.on}`)}))," "+t.join(" ")}_groupBy(e){return e?"string"==typeof e?` GROUP BY ${e}`:` GROUP BY ${e.join(", ")}`:""}_having(e){return e?` HAVING ${e}`:""}_orderBy(e){if(!e)return"";if("string"==typeof e)return` ORDER BY ${e}`;if(Array.isArray(e))return` ORDER BY ${e.join(", ")}`;const t=[];return Object.entries(e).forEach((([e,r])=>{t.push(`${e} ${r}`)})),` ORDER BY ${t.join(", ")}`}_limit(e){return e?` LIMIT ${e}`:""}_offset(e){return e?` OFFSET ${e}`:""}_returning(e){return e?"string"==typeof e?` RETURNING ${e}`:` RETURNING ${e.join(", ")}`:""}}exports.D1QB=class extends a{db;constructor(e){super(),this.db=e}async execute(e){let t=this.db.prepare(e.query);if(this._debugger&&console.log({"workers-qb":{query:e.query,arguments:e.arguments,fetchType:e.fetchType}}),e.arguments&&(t=t.bind(...e.arguments)),e.fetchType===exports.FetchTypes.ONE||e.fetchType===exports.FetchTypes.ALL){const r=await t.all();return{changes:r.meta?.changes,duration:r.meta?.duration,last_row_id:r.meta?.last_row_id,served_by:r.meta?.served_by,success:r.success,results:e.fetchType===exports.FetchTypes.ONE?r.results[0]:r.results}}return t.run()}async batchExecute(e){this._debugger&&console.log({"workers-qb":e});const t=e.map((e=>{let t=this.db.prepare(e.query);return e.arguments&&(t=t.bind(...e.arguments)),t}));return(await this.db.batch(t)).map(((t,r)=>e&&void 0!==e[r]&&e[r]?.fetchType?{changes:t.meta?.changes,duration:t.meta?.duration,last_row_id:t.meta?.last_row_id,served_by:t.meta?.served_by,success:t.success,results:e[r]?.fetchType===exports.FetchTypes.ONE?t.results?.[0]:t.results}:{changes:t.meta?.changes,duration:t.meta?.duration,last_row_id:t.meta?.last_row_id,served_by:t.meta?.served_by,success:t.success}))}},exports.PGQB=class extends a{db;constructor(e){super(),this.db=e}async connect(){await this.db.connect()}async close(){await this.db.end()}async execute(e){const t=e.query.replaceAll("?","$");let r;return this._debugger&&console.log({"workers-qb":e}),r=e.arguments?await this.db.query({values:e.arguments,text:t}):await this.db.query({text:t}),e.fetchType===exports.FetchTypes.ONE||e.fetchType===exports.FetchTypes.ALL?{command:r.command,lastRowId:r.oid,rowCount:r.rowCount,results:e.fetchType===exports.FetchTypes.ONE?r.rows[0]:r.rows}:{command:r.command,lastRowId:r.oid,rowCount:r.rowCount}}},exports.Query=o,exports.QueryBuilder=a,exports.Raw=n;
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
ConflictTypes: () => ConflictTypes,
D1QB: () => D1QB,
FetchTypes: () => FetchTypes,
JoinTypes: () => JoinTypes,
OrderTypes: () => OrderTypes,
PGQB: () => PGQB,
Query: () => Query,
QueryBuilder: () => QueryBuilder,
Raw: () => Raw
});
module.exports = __toCommonJS(src_exports);
// src/enums.ts
var OrderTypes = /* @__PURE__ */ ((OrderTypes3) => {
OrderTypes3["ASC"] = "ASC";
OrderTypes3["DESC"] = "DESC";
return OrderTypes3;
})(OrderTypes || {});
var FetchTypes = /* @__PURE__ */ ((FetchTypes2) => {
FetchTypes2["ONE"] = "ONE";
FetchTypes2["ALL"] = "ALL";
return FetchTypes2;
})(FetchTypes || {});
var ConflictTypes = /* @__PURE__ */ ((ConflictTypes3) => {
ConflictTypes3["ROLLBACK"] = "ROLLBACK";
ConflictTypes3["ABORT"] = "ABORT";
ConflictTypes3["FAIL"] = "FAIL";
ConflictTypes3["IGNORE"] = "IGNORE";
ConflictTypes3["REPLACE"] = "REPLACE";
return ConflictTypes3;
})(ConflictTypes || {});
var JoinTypes = /* @__PURE__ */ ((JoinTypes2) => {
JoinTypes2["INNER"] = "INNER";
JoinTypes2["LEFT"] = "LEFT";
JoinTypes2["CROSS"] = "CROSS";
return JoinTypes2;
})(JoinTypes || {});
// src/tools.ts
var Raw = class {
isRaw = true;
content;
constructor(content) {
this.content = content;
}
};
var Query = class {
executeMethod;
query;
arguments;
fetchType;
constructor(executeMethod, query, args, fetchType) {
this.executeMethod = executeMethod;
this.query = query;
this.arguments = args;
this.fetchType = fetchType;
}
async execute() {
return this.executeMethod(this);
}
};
// src/Builder.ts
var QueryBuilder = class {
_debugger = false;
setDebugger(state) {
this._debugger = state;
}
async execute(query) {
throw new Error("Execute method not implemented");
}
async batchExecute(queryArray) {
throw new Error("Batch execute method not implemented");
}
createTable(params) {
return new Query(
(q) => {
return this.execute(q);
},
`CREATE TABLE ${params.ifNotExists ? "IF NOT EXISTS" : ""} ${params.tableName}
( ${params.schema})`
);
}
dropTable(params) {
return new Query((q) => {
return this.execute(q);
}, `DROP TABLE ${params.ifExists ? "IF EXISTS" : ""} ${params.tableName}`);
}
fetchOne(params) {
return new Query(
(q) => {
return this.execute(q);
},
this._select({ ...params, limit: 1 }),
typeof params.where === "object" && !Array.isArray(params.where) && params.where?.params ? params.where?.params : void 0,
"ONE" /* ONE */
);
}
fetchAll(params) {
return new Query(
(q) => {
return this.execute(q);
},
this._select(params),
typeof params.where === "object" && !Array.isArray(params.where) && params.where?.params ? params.where?.params : void 0,
"ALL" /* ALL */
);
}
raw(params) {
return new Query(
(q) => {
return this.execute(q);
},
params.query,
params.args,
params.fetchType
);
}
insert(params) {
let args = [];
if (typeof params.onConflict === "object") {
if (typeof params.onConflict?.where === "object" && !Array.isArray(params.onConflict?.where) && params.onConflict?.where?.params) {
args = args.concat(params.onConflict.where?.params);
}
if (params.onConflict.data) {
args = args.concat(this._parse_arguments(params.onConflict.data));
}
}
if (Array.isArray(params.data)) {
for (const row of params.data) {
args = args.concat(this._parse_arguments(row));
}
} else {
args = args.concat(this._parse_arguments(params.data));
}
const fetchType = Array.isArray(params.data) ? "ALL" /* ALL */ : "ONE" /* ONE */;
return new Query(
(q) => {
return this.execute(q);
},
this._insert(params),
args,
fetchType
);
}
update(params) {
let args = this._parse_arguments(params.data);
if (typeof params.where === "object" && !Array.isArray(params.where) && params.where?.params) {
args = (params.where?.params).concat(args);
}
return new Query(
(q) => {
return this.execute(q);
},
this._update(params),
args,
"ALL" /* ALL */
);
}
delete(params) {
return new Query(
(q) => {
return this.execute(q);
},
this._delete(params),
typeof params.where === "object" && !Array.isArray(params.where) && params.where?.params ? params.where?.params : void 0,
"ALL" /* ALL */
);
}
_parse_arguments(row) {
return Object.values(row).filter((value) => {
return !(value instanceof Raw);
});
}
_onConflict(resolution) {
if (resolution) {
if (typeof resolution === "object") {
if (!Array.isArray(resolution.column)) {
resolution.column = [resolution.column];
}
const _update_query = this.update({
tableName: "_REPLACE_",
data: resolution.data,
where: resolution.where
}).query.replace(" _REPLACE_", "");
return ` ON CONFLICT (${resolution.column.join(", ")}) DO ${_update_query}`;
}
return `OR ${resolution} `;
}
return "";
}
_insert(params) {
const rows = [];
let data;
if (!Array.isArray(params.data)) {
data = [params.data];
} else {
data = params.data;
}
if (!data || !data[0] || data.length === 0) {
throw new Error("Insert data is undefined");
}
const columns = Object.keys(data[0]).join(", ");
let index = 1;
let orConflict = "", onConflict = "";
if (params.onConflict && typeof params.onConflict === "object") {
onConflict = this._onConflict(params.onConflict);
if (typeof params.onConflict?.where === "object" && !Array.isArray(params.onConflict?.where) && params.onConflict?.where?.params) {
index += (params.onConflict.where?.params).length;
}
if (params.onConflict.data) {
index += this._parse_arguments(params.onConflict.data).length;
}
} else {
orConflict = this._onConflict(params.onConflict);
}
for (const row of data) {
const values = [];
Object.values(row).forEach((value) => {
if (value instanceof Raw) {
values.push(value.content);
} else {
values.push(`?${index}`);
index += 1;
}
});
rows.push(`(${values.join(", ")})`);
}
return `INSERT ${orConflict} INTO ${params.tableName} (${columns}) VALUES ${rows.join(", ")}` + onConflict + this._returning(params.returning);
}
_update(params) {
const whereParamsLength = typeof params.where === "object" && !Array.isArray(params.where) && params.where?.params ? Object.keys(params.where?.params).length : 0;
const set = [];
let index = 1;
for (const [key, value] of Object.entries(params.data)) {
if (value instanceof Raw) {
set.push(`${key} = ${value.content}`);
} else {
set.push(`${key} = ?${whereParamsLength + index}`);
index += 1;
}
}
return `UPDATE ${this._onConflict(params.onConflict)}${params.tableName}
SET ${set.join(", ")}` + this._where(params.where) + this._returning(params.returning);
}
_delete(params) {
return `DELETE
FROM ${params.tableName}` + this._where(params.where) + this._returning(params.returning);
}
_select(params) {
return `SELECT ${this._fields(params.fields)}
FROM ${params.tableName}` + this._join(params.join) + this._where(params.where) + this._groupBy(params.groupBy) + this._having(params.having) + this._orderBy(params.orderBy) + this._limit(params.limit) + this._offset(params.offset);
}
_fields(value) {
if (!value) return "*";
if (typeof value === "string") return value;
return value.join(", ");
}
_where(value) {
if (!value) return "";
let conditions = value;
if (typeof value === "object" && !Array.isArray(value)) {
conditions = value.conditions;
}
if (typeof conditions === "string") return ` WHERE ${conditions.toString()}`;
if (conditions.length > 0) {
return ` WHERE ${conditions.join(" AND ")}`;
}
return "";
}
_join(value) {
if (!value) return "";
if (!Array.isArray(value)) {
value = [value];
}
const joinQuery = [];
value.forEach((item) => {
const type = item.type ? `${item.type} ` : "";
joinQuery.push(
`${type}JOIN ${typeof item.table === "string" ? item.table : `(${this._select(item.table)})`}${item.alias ? ` AS ${item.alias}` : ""} ON ${item.on}`
);
});
return " " + joinQuery.join(" ");
}
_groupBy(value) {
if (!value) return "";
if (typeof value === "string") return ` GROUP BY ${value}`;
return ` GROUP BY ${value.join(", ")}`;
}
_having(value) {
if (!value) return "";
return ` HAVING ${value}`;
}
_orderBy(value) {
if (!value) return "";
if (typeof value === "string") return ` ORDER BY ${value}`;
if (Array.isArray(value)) {
return ` ORDER BY ${value.join(", ")}`;
}
const order = [];
Object.entries(value).forEach(([key, item]) => {
order.push(`${key} ${item}`);
});
return ` ORDER BY ${order.join(", ")}`;
}
_limit(value) {
if (!value) return "";
return ` LIMIT ${value}`;
}
_offset(value) {
if (!value) return "";
return ` OFFSET ${value}`;
}
_returning(value) {
if (!value) return "";
if (typeof value === "string") return ` RETURNING ${value}`;
return ` RETURNING ${value.join(", ")}`;
}
};
// src/databases/d1.ts
var D1QB = class extends QueryBuilder {
db;
constructor(db) {
super();
this.db = db;
}
async execute(query) {
let stmt = this.db.prepare(query.query);
if (this._debugger) {
console.log({
"workers-qb": {
query: query.query,
arguments: query.arguments,
fetchType: query.fetchType
}
});
}
if (query.arguments) {
stmt = stmt.bind(...query.arguments);
}
if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
const resp = await stmt.all();
return {
changes: resp.meta?.changes,
duration: resp.meta?.duration,
last_row_id: resp.meta?.last_row_id,
served_by: resp.meta?.served_by,
success: resp.success,
results: query.fetchType === "ONE" /* ONE */ ? resp.results[0] : resp.results
};
}
return stmt.run();
}
async batchExecute(queryArray) {
if (this._debugger) {
console.log({
"workers-qb": queryArray
});
}
const statements = queryArray.map((query) => {
let stmt = this.db.prepare(query.query);
if (query.arguments) {
stmt = stmt.bind(...query.arguments);
}
return stmt;
});
const responses = await this.db.batch(statements);
return responses.map(
(resp, i) => {
if (queryArray && queryArray[i] !== void 0 && queryArray[i]?.fetchType) {
return {
changes: resp.meta?.changes,
duration: resp.meta?.duration,
last_row_id: resp.meta?.last_row_id,
served_by: resp.meta?.served_by,
success: resp.success,
results: queryArray[i]?.fetchType === "ONE" /* ONE */ ? resp.results?.[0] : resp.results
};
} else {
return {
changes: resp.meta?.changes,
duration: resp.meta?.duration,
last_row_id: resp.meta?.last_row_id,
served_by: resp.meta?.served_by,
success: resp.success
};
}
}
);
}
};
// src/databases/pg.ts
var PGQB = class extends QueryBuilder {
db;
constructor(db) {
super();
this.db = db;
}
async connect() {
await this.db.connect();
}
async close() {
await this.db.end();
}
async execute(query) {
const queryString = query.query.replaceAll("?", "$");
if (this._debugger) {
console.log({
"workers-qb": query
});
}
let result;
if (query.arguments) {
result = await this.db.query({
values: query.arguments,
text: queryString
});
} else {
result = await this.db.query({
text: queryString
});
}
if (query.fetchType === "ONE" /* ONE */ || query.fetchType === "ALL" /* ALL */) {
return {
command: result.command,
lastRowId: result.oid,
rowCount: result.rowCount,
results: query.fetchType === "ONE" /* ONE */ ? result.rows[0] : result.rows
};
}
return {
command: result.command,
lastRowId: result.oid,
rowCount: result.rowCount
};
}
};
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
ConflictTypes,
D1QB,
FetchTypes,
JoinTypes,
OrderTypes,
PGQB,
Query,
QueryBuilder,
Raw
});

36

package.json
{
"name": "workers-qb",
"version": "1.2.4",
"type": "module",
"version": "1.3.0",
"description": "Zero dependencies Query Builder for Cloudflare Workers",
"main": "./dist/index.js",
"types": "./dist/src/index.d.ts",
"exports": {
".": {
"types": "./dist/src/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
},
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [

@@ -21,9 +14,6 @@ "dist",

"scripts": {
"prepublishOnly": "pinst --disable",
"postpublish": "pinst --enable",
"build": "rollup -c",
"package": "npm run build && npm pack",
"build": "tsup src/index.ts --format cjs,esm --dts",
"lint": "tsc -p tsconfig.json",
"test": "jest --config jest.config.cjs --no-cache --runInBand",
"test:cov": "jest --config jest.config.cjs --coverage --no-cache --runInBand",
"addscope": "node tools/packagejson name @g4brym/workers-qb",
"prettify": "prettier --check . || (prettier -w .; exit 1)",

@@ -70,9 +60,6 @@ "prepare": "husky install"

"devDependencies": {
"@commitlint/cli": "^13.1.0",
"@commitlint/config-conventional": "^13.1.0",
"@rollup/plugin-terser": "^0.2.1",
"@rollup/plugin-typescript": "^10.0.1",
"@types/jest": "^27.0.1",
"@types/jest": "^29.5.12",
"@typescript-eslint/eslint-plugin": "^4.31.1",
"@typescript-eslint/parser": "^4.31.1",
"changesets": "^1.0.2",
"eslint": "^7.32.0",

@@ -82,9 +69,8 @@ "eslint-config-prettier": "^8.3.0",

"husky": "^7.0.2",
"jest": "^28.1.2",
"jest": "^29.7.0",
"pinst": "^2.1.6",
"prettier": "^2.4.0",
"rollup": "^3.8.1",
"rollup-plugin-bundle-size": "^1.0.3",
"ts-jest": "^28.0.5",
"typescript": "^4.8.4"
"ts-jest": "^29.1.4",
"tsup": "^8.1.0",
"typescript": "^5.4.5"
},

@@ -91,0 +77,0 @@ "prettier": {

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