Socket
Socket
Sign inDemoInstall

vite-plugin-cdn-import

Package Overview
Dependencies
Maintainers
1
Versions
17
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

vite-plugin-cdn-import - npm Package Compare versions

Comparing version 0.3.5 to 1.0.0-alpha.0

dist/index.cjs

75

dist/index.d.ts

@@ -1,3 +0,4 @@

import { Plugin } from 'vite';
import { HtmlTagDescriptor, Plugin } from 'vite';
type GetModuleFunc$1 = (prodUrl: string) => Module;
interface Module {

@@ -7,7 +8,16 @@ name: string;

path: string | string[];
/** Alias ​​of name, for example "react-dom/client" is an alias of "react-dom" */
alias?: string[];
css?: string | string[];
prodUrl?: string;
}
interface Options {
modules: (Module | ((prodUrl: string) => Module))[];
prodUrl?: string;
modules: (Module | Module[] | GetModuleFunc$1 | GetModuleFunc$1[])[];
/** Enabled in dev mode, default is false */
enableInDevMode?: boolean;
/** Generate the external script tag */
generateScriptTag?: (name: string, scriptUrl: string) => Omit<HtmlTagDescriptor, 'tag' | 'children'>;
/** Generate the external css link tag */
generateCssLinkTag?: (name: string, cssUrl: string) => Omit<HtmlTagDescriptor, 'tag' | 'children'>;
}

@@ -27,2 +37,3 @@

var: string;
alias: string[];
jsdeliver: {

@@ -45,3 +56,3 @@ path: string;

};
ahooks: {
vue: {
var: string;

@@ -52,3 +63,3 @@ jsdeliver: {

};
'@ant-design/charts': {
'vue-router': {
var: string;

@@ -59,5 +70,6 @@ jsdeliver: {

};
vue: {
'vue-router@3': {
var: string;
jsdeliver: {
name: string;
path: string;

@@ -73,14 +85,2 @@ };

};
'@vueuse/shared': {
var: string;
jsdeliver: {
path: string;
};
};
'@vueuse/core': {
var: string;
jsdeliver: {
path: string;
};
};
moment: {

@@ -92,3 +92,3 @@ var: string;

};
eventemitter3: {
dayjs: {
var: string;

@@ -99,20 +99,2 @@ jsdeliver: {

};
'file-saver': {
var: string;
jsdeliver: {
path: string;
};
};
'browser-md5-file': {
var: string;
jsdeliver: {
path: string;
};
};
xlsx: {
var: string;
jsdeliver: {
path: string;
};
};
axios: {

@@ -130,21 +112,10 @@ var: string;

};
'crypto-js': {
var: string;
jsdeliver: {
path: string;
};
};
localforage: {
var: string;
jsdeliver: {
path: string;
};
};
};
declare type ModuleName = keyof typeof modulesConfig;
declare function autoComplete(name: ModuleName): (prodUrl: string) => Module;
type ModuleName = keyof typeof modulesConfig;
type GetModuleFunc = (prodUrl: string) => Module;
declare function autoComplete(name: ModuleName): GetModuleFunc;
declare function autoComplete(name: ModuleName[]): GetModuleFunc[];
declare function PluginImportToCDN(options: Options): Plugin[];
export default PluginImportToCDN;
export { Options, PluginImportToCDN as Plugin, autoComplete };
export { type Options, PluginImportToCDN as Plugin, autoComplete, PluginImportToCDN as default };

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

"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }var __defProp = Object.defineProperty;
var __defProp = Object.defineProperty;
var __defProps = Object.defineProperties;

@@ -7,3 +7,3 @@ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;

var __propIsEnum = Object.prototype.propertyIsEnumerable;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, {enumerable: true, configurable: true, writable: true, value}) : obj[key] = value;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __spreadValues = (a, b) => {

@@ -23,12 +23,14 @@ for (var prop in b || (b = {}))

// src/index.ts
var _rolluppluginexternalglobals = require('rollup-plugin-external-globals'); var _rolluppluginexternalglobals2 = _interopRequireDefault(_rolluppluginexternalglobals);
var _fs = require('fs'); var _fs2 = _interopRequireDefault(_fs);
var _path = require('path'); var _path2 = _interopRequireDefault(_path);
import externalGlobals from "rollup-plugin-external-globals";
import { viteExternalsPlugin } from "vite-plugin-externals";
import fs from "fs";
import path from "path";
// src/autoComplete.ts
var isDev = process.env.NODE_ENV === "development";
var modulesConfig = {
"react": {
react: {
var: "React",
jsdeliver: {
path: "umd/react.production.min.js"
path: isDev ? "umd/react.development.js" : "umd/react.production.min.js"
}

@@ -38,4 +40,5 @@ },

var: "ReactDOM",
alias: ["react-dom/client"],
jsdeliver: {
path: "umd/react-dom.production.min.js"
path: isDev ? "umd/react-dom.development.js" : "umd/react-dom.production.min.js"
}

@@ -46,50 +49,39 @@ },

jsdeliver: {
path: "umd/react-router-dom.min.js"
path: "dist/umd/react-router-dom.production.min.js"
}
},
"antd": {
antd: {
var: "antd",
jsdeliver: {
path: "dist/antd.min.js",
css: "dist/antd.min.css"
css: "dist/reset.min.css"
}
},
"ahooks": {
var: "ahooks",
vue: {
var: "Vue",
jsdeliver: {
path: "dist/ahooks.js"
path: isDev ? "dist/vue.runtime.global.js" : "dist/vue.runtime.global.prod.js"
}
},
"@ant-design/charts": {
var: "charts",
"vue-router": {
var: "VueRouter",
jsdeliver: {
path: "dist/charts.min.js"
path: "dist/vue-router.global.min.js"
}
},
"vue": {
var: "Vue",
"vue-router@3": {
var: "VueRouter",
jsdeliver: {
path: "dist/vue.global.prod.js"
name: "vue-router",
path: "dist/vue-router.min.js"
}
},
"vue2": {
vue2: {
var: "Vue",
jsdeliver: {
name: "vue",
path: "dist/vue.runtime.min.js"
path: isDev ? "dist/vue.runtime.js" : "dist/vue.runtime.min.js"
}
},
"@vueuse/shared": {
var: "VueUse",
jsdeliver: {
path: "index.iife.min.js"
}
},
"@vueuse/core": {
var: "VueUse",
jsdeliver: {
path: "index.iife.min.js"
}
},
"moment": {
moment: {
var: "moment",

@@ -100,27 +92,9 @@ jsdeliver: {

},
"eventemitter3": {
var: "EventEmitter3",
dayjs: {
var: "dayjs",
jsdeliver: {
path: "umd/eventemitter3.min.js"
path: "dayjs.min.js"
}
},
"file-saver": {
var: "window",
jsdeliver: {
path: "dist/FileSaver.min.js"
}
},
"browser-md5-file": {
var: "browserMD5File",
jsdeliver: {
path: "dist/index.umd.min.js"
}
},
"xlsx": {
var: "XLSX",
jsdeliver: {
path: "dist/xlsx.full.min.js"
}
},
"axios": {
axios: {
var: "axios",

@@ -131,3 +105,3 @@ jsdeliver: {

},
"lodash": {
lodash: {
var: "_",

@@ -137,14 +111,2 @@ jsdeliver: {

}
},
"crypto-js": {
var: "crypto-js",
jsdeliver: {
path: "crypto-js.min.js"
}
},
"localforage": {
var: "localforage",
jsdeliver: {
path: "dist/localforage.min.js"
}
}

@@ -161,3 +123,3 @@ };

}
function autoComplete(name) {
function genModuleByName(name) {
const config = modulesConfig[name];

@@ -169,10 +131,15 @@ if (!config) {

if (isCdnjs(prodUrl)) {
throw new Error(`The configuration of module ${name} in ${prodUrl} does not exist `);
throw new Error(
`The configuration of module ${name} in ${prodUrl} does not exist `
);
} else {
if (!(isJsdeliver(prodUrl) || isUnpkg(prodUrl))) {
console.warn("Unknown prodUrl, using the jsdeliver rule");
console.warn(
"Unknown CDN, please ensure that this CDN supports jsdelivr rules"
);
}
return __spreadValues({
name,
var: config.var
var: config.var,
alias: config.alias
}, config.jsdeliver);

@@ -182,9 +149,18 @@ }

}
function autoComplete(name) {
if (Array.isArray(name)) {
return name.map(genModuleByName);
} else {
return genModuleByName(name);
}
}
var autoComplete_default = autoComplete;
// src/index.ts
var isDev2 = process.env.NODE_ENV === "development";
function getModuleVersion(name) {
const pwd = process.cwd();
const pkgFile = _path2.default.join(pwd, "node_modules", name, "package.json");
if (_fs2.default.existsSync(pkgFile)) {
const pkgJson = JSON.parse(_fs2.default.readFileSync(pkgFile, "utf8"));
const pkgFile = path.join(pwd, "node_modules", name, "package.json");
if (fs.existsSync(pkgFile)) {
const pkgJson = JSON.parse(fs.readFileSync(pkgFile, "utf8"));
return pkgJson.version;

@@ -198,3 +174,3 @@ }

function renderUrl(url, data) {
const {path: path2} = data;
const { path: path2 } = data;
if (isFullPath(path2)) {

@@ -205,68 +181,81 @@ url = path2;

}
function getModuleInfo(module, prodUrl) {
prodUrl = module.prodUrl || prodUrl;
let v = module;
const version = getModuleVersion(v.name);
let pathList = [];
if (!Array.isArray(v.path)) {
pathList.push(v.path);
} else {
pathList = v.path;
}
const data = __spreadProps(__spreadValues({}, v), {
version
});
pathList = pathList.map((p) => {
if (!version && !isFullPath(p)) {
throw new Error(
`modules: ${data.name} package.json file does not exist`
);
}
return renderUrl(prodUrl, __spreadProps(__spreadValues({}, data), {
path: p
}));
});
let css = v.css || [];
if (!Array.isArray(css) && css) {
css = [css];
}
const cssList = !Array.isArray(css) ? [] : css.map(
(c) => renderUrl(prodUrl, __spreadProps(__spreadValues({}, data), {
path: c
}))
);
return __spreadProps(__spreadValues({}, v), {
version,
pathList,
cssList
});
}
function PluginImportToCDN(options) {
const {
modules = [],
prodUrl = "https://cdn.jsdelivr.net/npm/{name}@{version}/{path}"
prodUrl = "https://cdn.jsdelivr.net/npm/{name}@{version}/{path}",
enableInDevMode = false,
generateCssLinkTag,
generateScriptTag
} = options;
let isBuild = false;
const data = modules.map((m) => {
let v;
if (typeof m === "function") {
v = m(prodUrl);
} else {
v = m;
}
const version = getModuleVersion(v.name);
let pathList = [];
if (!Array.isArray(v.path)) {
pathList.push(v.path);
} else {
pathList = v.path;
}
const data2 = __spreadProps(__spreadValues({}, v), {
version
});
pathList = pathList.map((p) => {
if (!version && !isFullPath(p)) {
throw new Error(`modules: ${data2.name} package.json file does not exist`);
}
return renderUrl(prodUrl, __spreadProps(__spreadValues({}, data2), {
path: p
}));
});
let css = v.css || [];
if (!Array.isArray(css) && css) {
css = [css];
}
const cssList = !Array.isArray(css) ? [] : css.map((c) => renderUrl(prodUrl, __spreadProps(__spreadValues({}, data2), {
path: c
})));
return __spreadProps(__spreadValues({}, v), {
version,
pathList,
cssList
});
});
const list = (Array.isArray(m) ? m : [m]).map(
(v) => typeof v === "function" ? v(prodUrl) : v
);
return list.map((v) => getModuleInfo(v, prodUrl));
}).flat();
const externalMap = {};
data.forEach((v) => {
externalMap[v.name] = v.var;
if (Array.isArray(v.alias)) {
v.alias.forEach((alias) => {
externalMap[alias] = v.var;
});
}
});
const externalLibs = Object.keys(externalMap);
const plugins = [
{
name: "vite-plugin-cdn-import",
config(_, {command}) {
const userConfig = {
enforce: "pre",
config(_, { command }) {
isBuild = command === "build";
let userConfig = {
build: {
rollupOptions: {}
rollupOptions: {
plugins: []
}
}
};
if (command === "build") {
isBuild = true;
userConfig.build.rollupOptions = {
external: [...externalLibs],
plugins: [_rolluppluginexternalglobals2.default.call(void 0, externalMap)]
};
} else {
isBuild = false;
if (isBuild) {
userConfig.build.rollupOptions.plugins = [
externalGlobals(externalMap)
];
}

@@ -276,16 +265,51 @@ return userConfig;

transformIndexHtml(html) {
const cssCode = data.map((v) => v.cssList.map((css) => `<link href="${css}" rel="stylesheet">`).join("\n")).filter((v) => v).join("\n");
const jsCode = !isBuild ? "" : data.map((p) => p.pathList.map((url) => `<script src="${url}"></script>`).join("\n")).join("\n");
return html.replace(/<\/title>/i, `</title>${cssCode}
${jsCode}`);
if (!isBuild && !enableInDevMode) {
return html;
}
const descriptors = [];
data.forEach((v) => {
v.pathList.forEach((url) => {
const cusomize = (generateScriptTag == null ? void 0 : generateScriptTag(v.name, url)) || {};
const attrs = __spreadValues({
src: url,
crossorigin: "anonymous"
}, cusomize.attrs);
descriptors.push(__spreadProps(__spreadValues({
tag: "script"
}, cusomize), {
attrs
}));
});
v.cssList.forEach((url) => {
const cusomize = (generateCssLinkTag == null ? void 0 : generateCssLinkTag(v.name, url)) || {};
const attrs = __spreadValues({
href: url,
rel: "stylesheet",
crossorigin: "anonymous"
}, cusomize.attrs);
descriptors.push(__spreadProps(__spreadValues({
tag: "link"
}, cusomize), {
attrs
}));
});
});
return descriptors;
}
}
];
if (isDev2 && enableInDevMode) {
plugins.push(
viteExternalsPlugin(externalMap, {
enforce: "pre"
})
);
}
return plugins;
}
var src_default = PluginImportToCDN;
exports.Plugin = PluginImportToCDN; exports.autoComplete = autoComplete; exports.default = src_default;
export {
PluginImportToCDN as Plugin,
autoComplete_default as autoComplete,
src_default as default
};
{
"name": "vite-plugin-cdn-import",
"version": "0.3.5",
"version": "1.0.0-alpha.0",
"description": "Import packages from CDN for the vite plugin",
"main": "dist/index.js",
"module": "dist/index.mjs",
"type": "module",
"main": "dist/index.cjs",
"module": "dist/index.js",
"types": "dist/index.d.ts",

@@ -25,7 +26,6 @@ "keywords": [

"dev": "npm run build -- --watch",
"example:vue": "npm -C example/vue run dev",
"example:react": "npm -C example/react run dev",
"example:vue:build": "npm -C example/vue run build",
"example:react:build": "npm -C example/react run build",
"build": "tsup src/index.ts --dts --format cjs,esm"
"build": "tsup src/index.ts --dts --format cjs,esm",
"example": "node ./scripts/run-example.js",
"prepublishOnly": "npm run build",
"prepare": "husky"
},

@@ -35,10 +35,24 @@ "author": "vfasky<vfasky@me.com>",

"devDependencies": {
"@types/node": "^15.3.0",
"tsup": "^4.10.1",
"typescript": "^4.2.4",
"vite": "^2.3.7"
"@types/node": "^20.12.7",
"chalk": "^5.3.0",
"execa": "^8.0.1",
"husky": "^9.0.11",
"lint-staged": "^15.2.2",
"prettier": "^3.2.5",
"tsup": "^8.0.2",
"typescript": "^5.4.5",
"vite": "^5.2.10"
},
"dependencies": {
"rollup-plugin-external-globals": "^0.6.1"
"rollup-plugin-external-globals": "^0.10.0",
"vite-plugin-externals": "^0.6.2"
},
"lint-staged": {
"*.{ts,js,tsx,json,css,scss,less}": [
"prettier --write"
],
"*.{scss,less}": [
"stylelint --fix"
]
}
}

@@ -32,3 +32,2 @@ # Import modules from CDN with vite plugin

// vite.config.js
import reactRefresh from '@vitejs/plugin-react-refresh'
import importToCDN from 'vite-plugin-cdn-import'

@@ -60,3 +59,2 @@

// vite.config.js
import reactRefresh from '@vitejs/plugin-react-refresh'
import importToCDN, { autoComplete } from 'vite-plugin-cdn-import'

@@ -67,8 +65,4 @@

importToCDN({
modules: [
autoComplete('react'),
autoComplete('react-dom')
],
modules: [autoComplete(['react', 'react-dom'])],
}),
reactRefresh(),
],

@@ -80,48 +74,79 @@ }

- react
- react-dom
- react-router-dom
- antd
- vue
- vue2
- vue-router
- vue-router@3
- moment
- dayjs
- axios
- lodash
## Options
### prodUrl
Global prodUrl attribute, template url that generates CND file path.
- REF: [prodUrl](https://github.com/shirotech/webpack-cdn-plugin?tab=readme-ov-file#produrlstring--unpkgcomnameversionpath)
- Type
```ts
{
prodUrl?: string
}
```
"react" | "react-dom" | "react-router-dom" |
"antd" | "ahooks" | "@ant-design/charts" |
"vue" | "vue2" | "@vueuse/shared" |
"@vueuse/core" | "moment" |
"eventemitter3" | "file-saver" |
"browser-md5-file" | "xlsx | "crypto-js" |
"axios" | "lodash" | "localforage"
- Default: <https://cdn.jsdelivr.net/npm/{name}@{version}/{path}>
### modules
external config
- Type
```ts
type GetModuleFunc = (prodUrl: string) => Module
{
modules: (Module | Module[] | GetModuleFunc | GetModuleFunc[])[]
}
```
### VueUse demo
### enableInDevMode
Enabled in dev mode
- Type: `boolean`
- Default:`false`
```js
import vue from '@vitejs/plugin-vue'
import importToCDN, { autoComplete } from 'vite-plugin-cdn-import'
> vite2, vite3 请确保开发模式 process.env.NODE_ENV === 'development'
export default {
plugins: [
vue(),
importToCDN({
modules: [
autoComplete('vue'), // vue2 use autoComplete('vue2')
autoComplete('@vueuse/shared'),
autoComplete('@vueuse/core')
],
}),
],
}
### generateScriptTag
Custom generated script tags
- Type
```ts
generateScriptTag?: (
name: string,
scriptUrl: string,
) => Omit<HtmlTagDescriptor, 'tag' | 'children'>
```
## Options
### generateCssLinkTag
Customize generated css link tags
| Name | Description | Type | Default |
| ------- | -------------------------------------------------------------------------------------------- | --------------- | ------------------------------------------------------ |
| prodUrl | Overrides the global prodUrl, allowing you to specify the CDN location for a specific module | string | <https://cdn.jsdelivr.net/npm/{name}@{version}/{path}> |
| modules | Modules config | Array`<Module>` / Array`<(prodUrl:string) => Module>` | - |
- Type
```ts
generateCssLinkTag?: (
name: string,
cssUrl: string,
) => Omit<HtmlTagDescriptor, 'tag' | 'children'>
```
### Module
| Name | Description | Type |
| ---- | ------------------------------------------------------------------------------------- | ----------------- |
| name | The name of the module you want to externalize | string |
| var | A variable that will be assigned to the module in global scope, Rollup requires this | string |
| path | Specify the load path on the CDN | string / string[] |
| css | You can alternatively specify multiple style sheets which will be loaded from the CDN | string / string[] |
| Name | Description | Type |
| ---- | --------------------------------------------- | ----------------- |
| name | package name | string |
| alias | Alias ​​of name, for example "react-dom/client" is an alias of "react-dom" | string[] |
| var | Variables assigned globally to the module| string |
| path | Specify the load path on the CDN | string / string[] |
| css | Multiple style sheets can be loaded from CDN addresses | string / string[] |
| prodUrl | Override global prodUrl | string / string[] |
## Other CDN pordUrl

@@ -138,1 +163,2 @@

- [rollup-plugin-external-globals](https://github.com/eight04/rollup-plugin-external-globals)
- [vite-plugin-externals](https://github.com/crcong/vite-plugin-externals)

@@ -30,3 +30,2 @@ # 从 CDN 加载 modules 的 vite 插件

// vite.config.js
import reactRefresh from '@vitejs/plugin-react-refresh'
import importToCDN from 'vite-plugin-cdn-import'

@@ -58,3 +57,2 @@

// vite.config.js
import reactRefresh from '@vitejs/plugin-react-refresh'
import importToCDN, { autoComplete } from 'vite-plugin-cdn-import'

@@ -65,8 +63,4 @@

importToCDN({
modules: [
autoComplete('react'),
autoComplete('react-dom')
],
modules: [autoComplete(['react', 'react-dom'])],
}),
reactRefresh(),
],

@@ -78,39 +72,66 @@ }

- react
- react-dom
- react-router-dom
- antd
- vue
- vue2
- vue-router
- vue-router@3
- moment
- dayjs
- axios
- lodash
## 参数
### prodUrl
全局 prodUrl 属性,生成 CND 文件路径的模板 url.
- REF: [prodUrl](https://github.com/shirotech/webpack-cdn-plugin?tab=readme-ov-file#produrlstring--unpkgcomnameversionpath)
- 类型
```ts
{
prodUrl?: string
}
```
"react" | "react-dom" | "react-router-dom" |
"antd" | "ahooks" | "@ant-design/charts" |
"vue" | "vue2" | "@vueuse/shared" |
"@vueuse/core" | "moment" |
"eventemitter3" | "file-saver" |
"browser-md5-file" | "xlsx | "crypto-js" |
"axios" | "lodash" | "localforage"
- 默认值: <https://cdn.jsdelivr.net/npm/{name}@{version}/{path}>
### modules
external 模块配置
- 类型
```ts
type GetModuleFunc = (prodUrl: string) => Module
{
modules: (Module | Module[] | GetModuleFunc | GetModuleFunc[])[]
}
```
### VueUse demo
### enableInDevMode
是否在开发模式中启用
- 类型: `boolean`
- 默认值:`false`
```js
import vue from '@vitejs/plugin-vue'
import importToCDN, { autoComplete } from 'vite-plugin-cdn-import'
> vite2, vite3 请确保开发模式 process.env.NODE_ENV === 'development'
export default {
plugins: [
vue(),
importToCDN({
modules: [
autoComplete('vue'), // vue2 使用 autoComplete('vue2')
autoComplete('@vueuse/shared'),
autoComplete('@vueuse/core')
],
}),
],
}
### generateScriptTag
自定义生成的 script 标签
- 类型
```ts
generateScriptTag?: (
name: string,
scriptUrl: string,
) => Omit<HtmlTagDescriptor, 'tag' | 'children'>
```
## 参数
### generateCssLinkTag
自定义生成 css link 标签
- 类型
```ts
generateCssLinkTag?: (
name: string,
cssUrl: string,
) => Omit<HtmlTagDescriptor, 'tag' | 'children'>
```
| Name | Description | Type | Default |
| ------- | ------------------------------------------------------ | --------------- | ------------------------------------------------------ |
| prodUrl | 覆盖全局 prodUrl 属性,允许为特定的模块指定 CDN 的位置 | string | <https://cdn.jsdelivr.net/npm/{name}@{version}/{path}> |
| modules | 模块配置 | Array`<Module>` / Array`<(prodUrl:string) => Module>` | - |
### Module 配置

@@ -121,5 +142,7 @@

| name | 需要 CDN 加速的包名称 | string |
| var | 全局分配给模块的变量,Rollup 需要这个变量名称 | string |
| alias | 名称的别名,例如“react-dom/client”是“react-dom”的别名 | string[] |
| var | 全局分配给模块的变量 | string |
| path | 指定 CDN 上的加载路径 | string / string[] |
| css | 可以指定从 CDN 地址上加载多个样式表 | string / string[] |
| prodUrl | 覆盖全局的 prodUrl | string / string[] |

@@ -137,1 +160,2 @@ ## 其他的 CDN pordUrl 地址

- [rollup-plugin-external-globals](https://github.com/eight04/rollup-plugin-external-globals)
- [vite-plugin-externals](https://github.com/crcong/vite-plugin-externals)
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