Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@module-federation/webpack-bundler-runtime

Package Overview
Dependencies
Maintainers
8
Versions
669
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@module-federation/webpack-bundler-runtime - npm Package Compare versions

Comparing version 0.0.0-next-20231220085130 to 0.0.0-next-20231221061836

dist/src/attachShareScopeMap.d.ts

193

dist/index.cjs.js
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var runtime = require('@module-federation/runtime');
var sdk = require('@module-federation/sdk');

@@ -25,4 +28,64 @@ function _interopNamespace(e) {

function attachShareScopeMap(webpackRequire) {
if (!webpackRequire.S || webpackRequire.federation.hasAttachShareScopeMap || !webpackRequire.federation.instance || !webpackRequire.federation.instance.shareScopeMap) {
return;
}
webpackRequire.S = webpackRequire.federation.instance.shareScopeMap;
webpackRequire.federation.hasAttachShareScopeMap = true;
}
var FEDERATION_SUPPORTED_TYPES = [
"script"
];
var ENCODE_NAME_PREFIX = "ENCODE_NAME_PREFIX";
function _array_like_to_array(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
return arr2;
}
function _array_with_holes(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterable_to_array_limit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally{
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally{
if (_d) throw _e;
}
}
return _arr;
}
function _non_iterable_rest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _sliced_to_array(arr, i) {
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _unsupported_iterable_to_array(o, minLen) {
if (!o) return;
if (typeof o === "string") return _array_like_to_array(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
function remotes(options) {
var chunkId = options.chunkId, promises = options.promises, chunkMapping = options.chunkMapping, idToExternalAndNameMapping = options.idToExternalAndNameMapping, webpackRequire = options.webpackRequire;
var chunkId = options.chunkId, promises = options.promises, chunkMapping = options.chunkMapping, idToExternalAndNameMapping = options.idToExternalAndNameMapping, webpackRequire = options.webpackRequire, idToRemoteMap = options.idToRemoteMap;
attachShareScopeMap(webpackRequire);
if (webpackRequire.o(chunkMapping, chunkId)) {

@@ -35,2 +98,3 @@ chunkMapping[chunkId].forEach(function(id) {

var data = idToExternalAndNameMapping[id];
var remoteInfos = idToRemoteMap[id];
// @ts-ignore seems not work

@@ -83,5 +147,2 @@ if (getScope.indexOf(data) >= 0) {

};
var useRuntimeLoad = [
"script"
].includes(data[3]) && data[4];
// eslint-disable-next-line no-var

@@ -94,5 +155,17 @@ var onFactory = function(factory) {

};
var extractUrlAndGlobal = function(urlAndGlobal) {
var index = urlAndGlobal.indexOf("@");
if (index <= 0 || index === urlAndGlobal.length - 1) {
throw new Error('Invalid request "'.concat(urlAndGlobal, '"'));
}
return [
urlAndGlobal.substring(index + 1),
urlAndGlobal.substring(0, index)
];
};
var onRemoteLoaded = function() {
try {
var remoteModuleName = data[4] + data[1].slice(1);
var _extractUrlAndGlobal = _sliced_to_array(extractUrlAndGlobal(remoteInfos[0].request), 2), _entryUrl = _extractUrlAndGlobal[0], globalName = _extractUrlAndGlobal[1];
var remoteName = sdk.decodeName(globalName, ENCODE_NAME_PREFIX);
var remoteModuleName = remoteName + data[1].slice(1);
return webpackRequire.federation.instance.loadRemote(remoteModuleName, {

@@ -105,2 +178,5 @@ loadFactory: false

};
var useRuntimeLoad = remoteInfos.length === 1 && [
"script"
].includes(remoteInfos[0].externalType) && remoteInfos[0].request;
if (useRuntimeLoad) {

@@ -115,21 +191,5 @@ handleFunction(onRemoteLoaded, data[2], 0, 0, onFactory, 1);

function proxyShareScopeMap(__webpack_require__) {
if (!__webpack_require__.S) {
return;
}
// @ts-ignore FIXME: ideal situation is import type from @module-federation/runtime/type ,but the compile will throw error
__webpack_require__.S = new Proxy(globalThis.__VMOK__.__SHARE__, {
get: function get(target, prop, receiver) {
return globalThis.__VMOK__.__SHARE__[prop];
},
set: function set(target, prop, value) {
globalThis.__VMOK__.__SHARE__[prop] = value;
return true;
}
});
}
function consumes(options) {
var chunkId = options.chunkId, promises = options.promises, chunkMapping = options.chunkMapping, installedModules = options.installedModules, moduleToHandlerMapping = options.moduleToHandlerMapping, webpackRequire = options.webpackRequire;
proxyShareScopeMap(webpackRequire);
attachShareScopeMap(webpackRequire);
if (webpackRequire.o(chunkMapping, chunkId)) {

@@ -179,4 +239,57 @@ chunkMapping[chunkId].forEach(function(id) {

function initializeSharing(shareScopeName, webpackRequire) {
return webpackRequire.federation.instance.initializeSharing(shareScopeName);
function initializeSharing(param) {
var shareScopeName = param.shareScopeName, webpackRequire = param.webpackRequire, initPromises = param.initPromises, initTokens = param.initTokens, initScope = param.initScope;
if (!initScope) initScope = [];
// handling circular init calls
var initToken = initTokens[shareScopeName];
if (!initToken) initToken = initTokens[shareScopeName] = {};
if (initScope.indexOf(initToken) >= 0) return;
initScope.push(initToken);
var promise = initPromises[shareScopeName];
if (promise) return promise;
var warn = function(msg) {
return typeof console !== "undefined" && console.warn && console.warn(msg);
};
var initExternal = function(id) {
var handleError = function(err) {
return warn("Initialization of sharing external failed: " + err);
};
try {
var module = webpackRequire(id);
if (!module) return;
var initFn = function(module) {
return module && module.init && module.init(webpackRequire.S[shareScopeName], initScope);
};
if (module.then) return promises.push(module.then(initFn, handleError));
var initResult = initFn(module);
// @ts-ignore
if (initResult && typeof initResult !== "boolean" && initResult.then) // @ts-ignore
return promises.push(initResult["catch"](handleError));
} catch (err) {
handleError(err);
}
};
var promises = webpackRequire.federation.instance.initializeSharing(shareScopeName);
attachShareScopeMap(webpackRequire);
var bundlerRuntimeRemotesOptions = webpackRequire.federation.bundlerRuntimeOptions.remotes;
if (bundlerRuntimeRemotesOptions) {
Object.keys(bundlerRuntimeRemotesOptions.idToRemoteMap).forEach(function(moduleId) {
var info = bundlerRuntimeRemotesOptions.idToRemoteMap[moduleId];
var externalModuleId = bundlerRuntimeRemotesOptions.idToExternalAndNameMapping[moduleId][2];
if (info.length > 1) {
initExternal(externalModuleId);
} else if (info.length === 1) {
var remoteInfo = info[0];
if (!FEDERATION_SUPPORTED_TYPES.includes(remoteInfo.externalType)) {
initExternal(externalModuleId);
}
}
});
}
if (!promises.length) {
return initPromises[shareScopeName] = true;
}
return initPromises[shareScopeName] = Promise.all(promises).then(function() {
return initPromises[shareScopeName] = true;
});
}

@@ -216,2 +329,24 @@

function initContainerEntry(options) {
var webpackRequire = options.webpackRequire, shareScope = options.shareScope, initScope = options.initScope, shareScopeKey = options.shareScopeKey;
if (!webpackRequire.S) return;
if (!webpackRequire.federation || !webpackRequire.federation.instance || !webpackRequire.federation.initOptions) return;
var name = shareScopeKey || "default";
webpackRequire.federation.instance.initOptions({
name: webpackRequire.federation.initOptions.name,
remotes: []
});
webpackRequire.federation.instance.initShareScopeMap(name, shareScope);
var prevShareScope = globalThis.__FEDERATION__.__SHARE__["default"];
if (prevShareScope) {
webpackRequire.federation.instance.initShareScopeMap(name, prevShareScope);
}
webpackRequire.S[name] = shareScope;
if (webpackRequire.federation.attachShareScopeMap) {
webpackRequire.federation.attachShareScopeMap(webpackRequire);
}
// @ts-ignore
return webpackRequire.I(name, initScope);
}
var federation = {

@@ -226,6 +361,10 @@ runtime: runtime__namespace,

S: {},
installInitialConsumes: installInitialConsumes
}
installInitialConsumes: installInitialConsumes,
initContainerEntry: initContainerEntry
},
attachShareScopeMap: attachShareScopeMap,
bundlerRuntimeOptions: {}
};
module.exports = federation;
exports.ENCODE_NAME_PREFIX = ENCODE_NAME_PREFIX;
exports["default"] = federation;
import * as runtime from '@module-federation/runtime';
import { decodeName } from '@module-federation/sdk';
function attachShareScopeMap(webpackRequire) {
if (!webpackRequire.S || webpackRequire.federation.hasAttachShareScopeMap || !webpackRequire.federation.instance || !webpackRequire.federation.instance.shareScopeMap) {
return;
}
webpackRequire.S = webpackRequire.federation.instance.shareScopeMap;
webpackRequire.federation.hasAttachShareScopeMap = true;
}
var FEDERATION_SUPPORTED_TYPES = [
"script"
];
var ENCODE_NAME_PREFIX = "ENCODE_NAME_PREFIX";
function _array_like_to_array(arr, len) {
if (len == null || len > arr.length) len = arr.length;
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
return arr2;
}
function _array_with_holes(arr) {
if (Array.isArray(arr)) return arr;
}
function _iterable_to_array_limit(arr, i) {
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
if (_i == null) return;
var _arr = [];
var _n = true;
var _d = false;
var _s, _e;
try {
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
_arr.push(_s.value);
if (i && _arr.length === i) break;
}
} catch (err) {
_d = true;
_e = err;
} finally{
try {
if (!_n && _i["return"] != null) _i["return"]();
} finally{
if (_d) throw _e;
}
}
return _arr;
}
function _non_iterable_rest() {
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
function _sliced_to_array(arr, i) {
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
}
function _unsupported_iterable_to_array(o, minLen) {
if (!o) return;
if (typeof o === "string") return _array_like_to_array(o, minLen);
var n = Object.prototype.toString.call(o).slice(8, -1);
if (n === "Object" && o.constructor) n = o.constructor.name;
if (n === "Map" || n === "Set") return Array.from(n);
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
}
function remotes(options) {
var chunkId = options.chunkId, promises = options.promises, chunkMapping = options.chunkMapping, idToExternalAndNameMapping = options.idToExternalAndNameMapping, webpackRequire = options.webpackRequire;
var chunkId = options.chunkId, promises = options.promises, chunkMapping = options.chunkMapping, idToExternalAndNameMapping = options.idToExternalAndNameMapping, webpackRequire = options.webpackRequire, idToRemoteMap = options.idToRemoteMap;
attachShareScopeMap(webpackRequire);
if (webpackRequire.o(chunkMapping, chunkId)) {

@@ -12,2 +73,3 @@ chunkMapping[chunkId].forEach(function(id) {

var data = idToExternalAndNameMapping[id];
var remoteInfos = idToRemoteMap[id];
// @ts-ignore seems not work

@@ -60,5 +122,2 @@ if (getScope.indexOf(data) >= 0) {

};
var useRuntimeLoad = [
"script"
].includes(data[3]) && data[4];
// eslint-disable-next-line no-var

@@ -71,5 +130,17 @@ var onFactory = function(factory) {

};
var extractUrlAndGlobal = function(urlAndGlobal) {
var index = urlAndGlobal.indexOf("@");
if (index <= 0 || index === urlAndGlobal.length - 1) {
throw new Error('Invalid request "'.concat(urlAndGlobal, '"'));
}
return [
urlAndGlobal.substring(index + 1),
urlAndGlobal.substring(0, index)
];
};
var onRemoteLoaded = function() {
try {
var remoteModuleName = data[4] + data[1].slice(1);
var _extractUrlAndGlobal = _sliced_to_array(extractUrlAndGlobal(remoteInfos[0].request), 2), _entryUrl = _extractUrlAndGlobal[0], globalName = _extractUrlAndGlobal[1];
var remoteName = decodeName(globalName, ENCODE_NAME_PREFIX);
var remoteModuleName = remoteName + data[1].slice(1);
return webpackRequire.federation.instance.loadRemote(remoteModuleName, {

@@ -82,2 +153,5 @@ loadFactory: false

};
var useRuntimeLoad = remoteInfos.length === 1 && [
"script"
].includes(remoteInfos[0].externalType) && remoteInfos[0].request;
if (useRuntimeLoad) {

@@ -92,21 +166,5 @@ handleFunction(onRemoteLoaded, data[2], 0, 0, onFactory, 1);

function proxyShareScopeMap(__webpack_require__) {
if (!__webpack_require__.S) {
return;
}
// @ts-ignore FIXME: ideal situation is import type from @module-federation/runtime/type ,but the compile will throw error
__webpack_require__.S = new Proxy(globalThis.__VMOK__.__SHARE__, {
get: function get(target, prop, receiver) {
return globalThis.__VMOK__.__SHARE__[prop];
},
set: function set(target, prop, value) {
globalThis.__VMOK__.__SHARE__[prop] = value;
return true;
}
});
}
function consumes(options) {
var chunkId = options.chunkId, promises = options.promises, chunkMapping = options.chunkMapping, installedModules = options.installedModules, moduleToHandlerMapping = options.moduleToHandlerMapping, webpackRequire = options.webpackRequire;
proxyShareScopeMap(webpackRequire);
attachShareScopeMap(webpackRequire);
if (webpackRequire.o(chunkMapping, chunkId)) {

@@ -156,4 +214,57 @@ chunkMapping[chunkId].forEach(function(id) {

function initializeSharing(shareScopeName, webpackRequire) {
return webpackRequire.federation.instance.initializeSharing(shareScopeName);
function initializeSharing(param) {
var shareScopeName = param.shareScopeName, webpackRequire = param.webpackRequire, initPromises = param.initPromises, initTokens = param.initTokens, initScope = param.initScope;
if (!initScope) initScope = [];
// handling circular init calls
var initToken = initTokens[shareScopeName];
if (!initToken) initToken = initTokens[shareScopeName] = {};
if (initScope.indexOf(initToken) >= 0) return;
initScope.push(initToken);
var promise = initPromises[shareScopeName];
if (promise) return promise;
var warn = function(msg) {
return typeof console !== "undefined" && console.warn && console.warn(msg);
};
var initExternal = function(id) {
var handleError = function(err) {
return warn("Initialization of sharing external failed: " + err);
};
try {
var module = webpackRequire(id);
if (!module) return;
var initFn = function(module) {
return module && module.init && module.init(webpackRequire.S[shareScopeName], initScope);
};
if (module.then) return promises.push(module.then(initFn, handleError));
var initResult = initFn(module);
// @ts-ignore
if (initResult && typeof initResult !== "boolean" && initResult.then) // @ts-ignore
return promises.push(initResult["catch"](handleError));
} catch (err) {
handleError(err);
}
};
var promises = webpackRequire.federation.instance.initializeSharing(shareScopeName);
attachShareScopeMap(webpackRequire);
var bundlerRuntimeRemotesOptions = webpackRequire.federation.bundlerRuntimeOptions.remotes;
if (bundlerRuntimeRemotesOptions) {
Object.keys(bundlerRuntimeRemotesOptions.idToRemoteMap).forEach(function(moduleId) {
var info = bundlerRuntimeRemotesOptions.idToRemoteMap[moduleId];
var externalModuleId = bundlerRuntimeRemotesOptions.idToExternalAndNameMapping[moduleId][2];
if (info.length > 1) {
initExternal(externalModuleId);
} else if (info.length === 1) {
var remoteInfo = info[0];
if (!FEDERATION_SUPPORTED_TYPES.includes(remoteInfo.externalType)) {
initExternal(externalModuleId);
}
}
});
}
if (!promises.length) {
return initPromises[shareScopeName] = true;
}
return initPromises[shareScopeName] = Promise.all(promises).then(function() {
return initPromises[shareScopeName] = true;
});
}

@@ -193,2 +304,24 @@

function initContainerEntry(options) {
var webpackRequire = options.webpackRequire, shareScope = options.shareScope, initScope = options.initScope, shareScopeKey = options.shareScopeKey;
if (!webpackRequire.S) return;
if (!webpackRequire.federation || !webpackRequire.federation.instance || !webpackRequire.federation.initOptions) return;
var name = shareScopeKey || "default";
webpackRequire.federation.instance.initOptions({
name: webpackRequire.federation.initOptions.name,
remotes: []
});
webpackRequire.federation.instance.initShareScopeMap(name, shareScope);
var prevShareScope = globalThis.__FEDERATION__.__SHARE__["default"];
if (prevShareScope) {
webpackRequire.federation.instance.initShareScopeMap(name, prevShareScope);
}
webpackRequire.S[name] = shareScope;
if (webpackRequire.federation.attachShareScopeMap) {
webpackRequire.federation.attachShareScopeMap(webpackRequire);
}
// @ts-ignore
return webpackRequire.I(name, initScope);
}
var federation = {

@@ -203,6 +336,9 @@ runtime: runtime,

S: {},
installInitialConsumes: installInitialConsumes
}
installInitialConsumes: installInitialConsumes,
initContainerEntry: initContainerEntry
},
attachShareScopeMap: attachShareScopeMap,
bundlerRuntimeOptions: {}
};
export { federation as default };
export { ENCODE_NAME_PREFIX, federation as default };

7

dist/package.json
{
"public": true,
"name": "@module-federation/webpack-bundler-runtime",
"version": "0.0.3",
"version": "0.0.4",
"license": "MIT",

@@ -21,6 +21,7 @@ "description": "Module Federation Runtime for webpack",

"module": "./index.esm.js",
"types": "./index.cjs.d.ts",
"types": "./dist/index.cjs.d.ts",
"dependencies": {
"@module-federation/runtime": "workspace:*"
"@module-federation/runtime": "workspace:*",
"@module-federation/sdk": "workspace:*"
}
}
import { Federation } from './types';
export * from './types';
export { ENCODE_NAME_PREFIX } from './constant';
declare const federation: Federation;
export default federation;

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

import { WebpackRequire } from './types';
export declare function initializeSharing(shareScopeName: string, webpackRequire: WebpackRequire): Promise<boolean> | boolean;
import { InitializeSharingOptions } from './types';
export declare function initializeSharing({ shareScopeName, webpackRequire, initPromises, initTokens, initScope, }: InitializeSharingOptions): Promise<boolean> | boolean | void;
import * as runtime from '@module-federation/runtime';
import { initializeSharing } from './initializeSharing';
import { attachShareScopeMap } from './attachShareScopeMap';
import { initContainerEntry } from './initContainerEntry';
type ExcludeUndefined<T> = T extends undefined ? never : T;

@@ -11,2 +13,11 @@ type NonUndefined<T = Shared> = ExcludeUndefined<T>;

type InferredModule = InferModule<ModuleCache>;
export type ShareScopeMap = runtime.FederationHost['shareScopeMap'];
type InitToken = Record<string, Record<string, any>>;
export interface InitializeSharingOptions {
shareScopeName: string;
webpackRequire: WebpackRequire;
initPromises: Record<string, Promise<boolean> | boolean>;
initTokens: InitToken;
initScope: InitToken[];
}
export type RemoteEntryExports = NonUndefined<InferredModule['remoteEntryExports']>;

@@ -20,9 +31,3 @@ type ExtractInitParameters<T> = T extends {

};
type IdToExternalAndNameMappingItem = [
string,
string,
string | number,
string,
string
];
type IdToExternalAndNameMappingItem = [string, string, string | number];
interface IdToExternalAndNameMappingItemWithPromise extends IdToExternalAndNameMappingItem {

@@ -37,3 +42,3 @@ p?: Promise<any> | number;

c: Record<string, any>;
I: typeof initializeSharing;
I: (scopeName: string, initScope?: InitializeSharingOptions['initScope']) => ReturnType<typeof initializeSharing>;
S?: InferredGlobalShareScope;

@@ -51,2 +56,7 @@ federation: Federation;

}
interface IdToRemoteMapItem {
externalType: string;
request: string;
externalModuleId?: string | number;
}
export interface RemotesOptions {

@@ -57,2 +67,3 @@ chunkId: string | number;

idToExternalAndNameMapping: Record<string, IdToExternalAndNameMappingItemWithPromise>;
idToRemoteMap: Record<string, IdToRemoteMapItem[]>;
webpackRequire: WebpackRequire;

@@ -79,2 +90,8 @@ }

}
export interface InitContainerEntryOptions {
shareScope: ShareScopeMap[string];
shareScopeKey: string;
webpackRequire: WebpackRequire;
initScope?: InitializeSharingOptions['initScope'];
}
export interface Federation {

@@ -88,7 +105,13 @@ runtime?: typeof runtime;

consumes: (options: ConsumesOptions) => void;
I: (name: string, webpackRequire: WebpackRequire) => Promise<boolean> | boolean;
I: typeof initializeSharing;
S: InferredGlobalShareScope;
installInitialConsumes: (options: InstallInitialConsumesOptions) => any;
initContainerEntry: typeof initContainerEntry;
};
bundlerRuntimeOptions: {
remotes?: Exclude<RemotesOptions, 'chunkId' | 'promises'>;
};
attachShareScopeMap?: typeof attachShareScopeMap;
hasAttachShareScopeMap?: boolean;
}
export {};
{
"public": true,
"name": "@module-federation/webpack-bundler-runtime",
"version": "0.0.0-next-20231220085130",
"version": "0.0.0-next-20231221061836",
"license": "MIT",

@@ -19,8 +19,9 @@ "description": "Module Federation Runtime for webpack",

"author": "zhanghang <hanric.zhang@gmail.com>",
"main": "./index.cjs.js",
"module": "./index.esm.js",
"types": "./index.cjs.d.ts",
"main": "./dist/index.cjs.js",
"module": "./dist/index.esm.js",
"types": "./dist/index.cjs.d.ts",
"dependencies": {
"@module-federation/runtime": "0.0.0-next-20231220085130"
"@module-federation/runtime": "0.0.0-next-20231221061836",
"@module-federation/sdk": "0.0.0-next-20231221061836"
}
}
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