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

@teleporthq/teleport-shared

Package Overview
Dependencies
Maintainers
2
Versions
116
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@teleporthq/teleport-shared - npm Package Compare versions

Comparing version 0.32.0-alpha.0 to 0.32.0

6

__tests__/utils/string-utils.ts

@@ -132,2 +132,8 @@ import {

})
it('works with multiple upper case characters to be in a sequence', () => {
expect(camelCaseToDashCase('PRImaryButton')).toBe('pr-imary-button')
})
it('works with single upper case words', () => {
expect(camelCaseToDashCase('AiAmAComponent')).toBe('ai-am-a-component')
})
})

@@ -134,0 +140,0 @@

2

dist/cjs/utils/string-utils.js

@@ -5,3 +5,3 @@ "use strict";

var camelCaseToDashCase = function (str) {
return str.replace(/([a-z])(?=[A-Z])|([A-Z0-9])(?=[A-Z][a-z])/g, '$1-').toLowerCase();
return str.replace(/([a-z])(?=[A-Z])|([A-Z0-9])(?=[A-Z][a-z])/g, '$1$2-').toLowerCase();
};

@@ -8,0 +8,0 @@ exports.camelCaseToDashCase = camelCaseToDashCase;

@@ -39,3 +39,3 @@ import { ComponentUIDL, UIDLStyleDefinitions, UIDLConditionalNode, UIDLElement, UIDLNode, UIDLStaticValue, UIDLAttributeValue, UIDLDynamicReference, UIDLRepeatContent, UIDLRepeatMeta, UIDLElementNode, UIDLDependency, UIDLStyleValue, UIDLStyleSheetContent, UIDLComponentStyleReference, UIDLRootComponent, UIDLResourceItem, GeneratorOptions } from '@teleporthq/teleport-types';

export declare const transformStylesAssignmentsToJson: (styleObject: Record<string, unknown>) => UIDLStyleDefinitions;
export declare const transformAttributesAssignmentsToJson: (attributesObject: Record<string, unknown>) => Record<string, UIDLAttributeValue>;
export declare const transformAttributesAssignmentsToJson: (attributesObject: Record<string, unknown>, isLocalComponent?: boolean) => Record<string, UIDLAttributeValue>;
export declare const findFirstElementNode: (node: UIDLNode) => UIDLElementNode;

@@ -42,0 +42,0 @@ export declare const removeChildNodes: (node: UIDLNode, criteria: (element: UIDLNode) => boolean) => void;

@@ -110,5 +110,8 @@ "use strict";

}
if (!originalString.startsWith('/')) {
if (typeof originalString !== 'string') {
return originalString;
}
if (!(originalString === null || originalString === void 0 ? void 0 : originalString.startsWith('/'))) {
return originalString;
}
var prefix = assets.prefix, _a = assets.mappings, mappings = _a === void 0 ? {} : _a, identifier = assets.identifier;

@@ -156,3 +159,3 @@ var assetName = (0, path_1.basename)(originalString);

var traverseNodes = function (node, fn, parent) {
var _a, _b, _c;
var _a, _b, _c, _d, _e, _f;
if (parent === void 0) { parent = null; }

@@ -162,3 +165,3 @@ fn(node, parent);

case 'element':
var _d = node.content, attrs_1 = _d.attrs, children = _d.children, style = _d.style, abilities = _d.abilities, referencedStyles = _d.referencedStyles;
var _g = node.content, attrs_1 = _g.attrs, children = _g.children, style = _g.style, abilities = _g.abilities, referencedStyles = _g.referencedStyles;
if (attrs_1) {

@@ -212,2 +215,13 @@ Object.keys(attrs_1).forEach(function (attrKey) {

break;
case 'cms-mixed-type':
if ((_d = node.content.nodes) === null || _d === void 0 ? void 0 : _d.fallback) {
(0, exports.traverseNodes)(node.content.nodes.fallback, fn);
}
if ((_e = node.content.nodes) === null || _e === void 0 ? void 0 : _e.error) {
(0, exports.traverseNodes)(node.content.nodes.error, fn);
}
Object.keys(((_f = node.content) === null || _f === void 0 ? void 0 : _f.mappings) || {}).forEach(function (key) {
(0, exports.traverseNodes)(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -232,2 +246,3 @@ (0, exports.traverseNodes)(node.content.node, fn, node);

case 'raw':
case 'inject':
break;

@@ -240,2 +255,3 @@ default:

var traverseResources = function (node, fn) {
var _a, _b, _c;
switch (node.type) {

@@ -274,2 +290,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
(0, exports.traverseResources)(node.content.nodes.fallback, fn);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
(0, exports.traverseResources)(node.content.nodes.error, fn);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
(0, exports.traverseResources)(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -307,2 +334,3 @@ (0, exports.traverseResources)(node.content.node, fn);

var traverseElements = function (node, fn) {
var _a, _b, _c;
switch (node.type) {

@@ -341,2 +369,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
(0, exports.traverseElements)(node.content.nodes.fallback, fn);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
(0, exports.traverseElements)(node.content.nodes.error, fn);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
(0, exports.traverseElements)(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -355,2 +394,3 @@ (0, exports.traverseElements)(node.content.node, fn);

case 'dynamic':
case 'inject':
case 'raw':

@@ -365,2 +405,3 @@ case 'expr':

var traverseRepeats = function (node, fn) {
var _a, _b, _c;
switch (node.type) {

@@ -398,2 +439,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
(0, exports.traverseRepeats)(node.content.nodes.fallback, fn);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
(0, exports.traverseRepeats)(node.content.nodes.error, fn);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
(0, exports.traverseRepeats)(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -415,2 +467,3 @@ fn(node.content);

case 'expr':
case 'inject':
break;

@@ -554,4 +607,11 @@ default:

exports.transformStylesAssignmentsToJson = transformStylesAssignmentsToJson;
var transformAttributesAssignmentsToJson = function (attributesObject) {
var newStyleObject = {};
/*
All the props passed to the components are transformed to a unique case
to minimize the collision of using cameCalse in one place and dashCase in
another place. So, all the attrs that are being passed to the local compoenents
need to be transformed since these are basically props.
*/
var transformAttributesAssignmentsToJson = function (attributesObject, isLocalComponent) {
if (isLocalComponent === void 0) { isLocalComponent = false; }
var newAttrObject = {};
Object.keys(attributesObject).reduce(function (acc, key) {

@@ -561,3 +621,4 @@ var attributeContent = attributesObject[key];

if (['string', 'number'].indexOf(entityType) !== -1) {
acc[key] = (0, exports.transformStringAssignmentToJson)(attributeContent);
var propKey = isLocalComponent ? __1.StringUtils.createStateOrPropStoringValue(key) : key;
acc[propKey] = (0, exports.transformStringAssignmentToJson)(attributeContent);
return acc;

@@ -569,3 +630,4 @@ }

if (['static', 'import', 'raw', 'expr'].indexOf(type) !== -1) {
acc[key] = attributeContent;
var propKey = isLocalComponent ? __1.StringUtils.createStateOrPropStoringValue(key) : key;
acc[propKey] = attributeContent;
return acc;

@@ -595,4 +657,4 @@ }

}
}, newStyleObject);
return newStyleObject;
}, newAttrObject);
return newAttrObject;
};

@@ -618,2 +680,3 @@ exports.transformAttributesAssignmentsToJson = transformAttributesAssignmentsToJson;

var removeChildNodes = function (node, criteria) {
var _a, _b, _c;
switch (node.type) {

@@ -655,2 +718,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
(0, exports.removeChildNodes)(node.content.nodes.fallback, criteria);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
(0, exports.removeChildNodes)(node.content.nodes.error, criteria);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
(0, exports.removeChildNodes)(node.content.mappings[key], criteria);
});
break;
case 'conditional':

@@ -668,2 +742,3 @@ (0, exports.removeChildNodes)(node.content.node, criteria);

case 'expr':
case 'inject':
break;

@@ -670,0 +745,0 @@ default:

export var camelCaseToDashCase = function (str) {
return str.replace(/([a-z])(?=[A-Z])|([A-Z0-9])(?=[A-Z][a-z])/g, '$1-').toLowerCase();
return str.replace(/([a-z])(?=[A-Z])|([A-Z0-9])(?=[A-Z][a-z])/g, '$1$2-').toLowerCase();
};

@@ -4,0 +4,0 @@ export var dashCaseToCamelCase = function (str) {

@@ -39,3 +39,3 @@ import { ComponentUIDL, UIDLStyleDefinitions, UIDLConditionalNode, UIDLElement, UIDLNode, UIDLStaticValue, UIDLAttributeValue, UIDLDynamicReference, UIDLRepeatContent, UIDLRepeatMeta, UIDLElementNode, UIDLDependency, UIDLStyleValue, UIDLStyleSheetContent, UIDLComponentStyleReference, UIDLRootComponent, UIDLResourceItem, GeneratorOptions } from '@teleporthq/teleport-types';

export declare const transformStylesAssignmentsToJson: (styleObject: Record<string, unknown>) => UIDLStyleDefinitions;
export declare const transformAttributesAssignmentsToJson: (attributesObject: Record<string, unknown>) => Record<string, UIDLAttributeValue>;
export declare const transformAttributesAssignmentsToJson: (attributesObject: Record<string, unknown>, isLocalComponent?: boolean) => Record<string, UIDLAttributeValue>;
export declare const findFirstElementNode: (node: UIDLNode) => UIDLElementNode;

@@ -42,0 +42,0 @@ export declare const removeChildNodes: (node: UIDLNode, criteria: (element: UIDLNode) => boolean) => void;

@@ -98,5 +98,8 @@ var __assign = (this && this.__assign) || function () {

}
if (!originalString.startsWith('/')) {
if (typeof originalString !== 'string') {
return originalString;
}
if (!(originalString === null || originalString === void 0 ? void 0 : originalString.startsWith('/'))) {
return originalString;
}
var prefix = assets.prefix, _a = assets.mappings, mappings = _a === void 0 ? {} : _a, identifier = assets.identifier;

@@ -142,3 +145,3 @@ var assetName = basename(originalString);

export var traverseNodes = function (node, fn, parent) {
var _a, _b, _c;
var _a, _b, _c, _d, _e, _f;
if (parent === void 0) { parent = null; }

@@ -148,3 +151,3 @@ fn(node, parent);

case 'element':
var _d = node.content, attrs_1 = _d.attrs, children = _d.children, style = _d.style, abilities = _d.abilities, referencedStyles = _d.referencedStyles;
var _g = node.content, attrs_1 = _g.attrs, children = _g.children, style = _g.style, abilities = _g.abilities, referencedStyles = _g.referencedStyles;
if (attrs_1) {

@@ -198,2 +201,13 @@ Object.keys(attrs_1).forEach(function (attrKey) {

break;
case 'cms-mixed-type':
if ((_d = node.content.nodes) === null || _d === void 0 ? void 0 : _d.fallback) {
traverseNodes(node.content.nodes.fallback, fn);
}
if ((_e = node.content.nodes) === null || _e === void 0 ? void 0 : _e.error) {
traverseNodes(node.content.nodes.error, fn);
}
Object.keys(((_f = node.content) === null || _f === void 0 ? void 0 : _f.mappings) || {}).forEach(function (key) {
traverseNodes(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -218,2 +232,3 @@ traverseNodes(node.content.node, fn, node);

case 'raw':
case 'inject':
break;

@@ -225,2 +240,3 @@ default:

export var traverseResources = function (node, fn) {
var _a, _b, _c;
switch (node.type) {

@@ -259,2 +275,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
traverseResources(node.content.nodes.fallback, fn);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
traverseResources(node.content.nodes.error, fn);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
traverseResources(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -291,2 +318,3 @@ traverseResources(node.content.node, fn);

export var traverseElements = function (node, fn) {
var _a, _b, _c;
switch (node.type) {

@@ -325,2 +353,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
traverseElements(node.content.nodes.fallback, fn);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
traverseElements(node.content.nodes.error, fn);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
traverseElements(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -339,2 +378,3 @@ traverseElements(node.content.node, fn);

case 'dynamic':
case 'inject':
case 'raw':

@@ -348,2 +388,3 @@ case 'expr':

export var traverseRepeats = function (node, fn) {
var _a, _b, _c;
switch (node.type) {

@@ -381,2 +422,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
traverseRepeats(node.content.nodes.fallback, fn);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
traverseRepeats(node.content.nodes.error, fn);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
traverseRepeats(node.content.mappings[key], fn);
});
break;
case 'repeat':

@@ -398,2 +450,3 @@ fn(node.content);

case 'expr':
case 'inject':
break;

@@ -531,4 +584,11 @@ default:

};
export var transformAttributesAssignmentsToJson = function (attributesObject) {
var newStyleObject = {};
/*
All the props passed to the components are transformed to a unique case
to minimize the collision of using cameCalse in one place and dashCase in
another place. So, all the attrs that are being passed to the local compoenents
need to be transformed since these are basically props.
*/
export var transformAttributesAssignmentsToJson = function (attributesObject, isLocalComponent) {
if (isLocalComponent === void 0) { isLocalComponent = false; }
var newAttrObject = {};
Object.keys(attributesObject).reduce(function (acc, key) {

@@ -538,3 +598,4 @@ var attributeContent = attributesObject[key];

if (['string', 'number'].indexOf(entityType) !== -1) {
acc[key] = transformStringAssignmentToJson(attributeContent);
var propKey = isLocalComponent ? StringUtils.createStateOrPropStoringValue(key) : key;
acc[propKey] = transformStringAssignmentToJson(attributeContent);
return acc;

@@ -546,3 +607,4 @@ }

if (['static', 'import', 'raw', 'expr'].indexOf(type) !== -1) {
acc[key] = attributeContent;
var propKey = isLocalComponent ? StringUtils.createStateOrPropStoringValue(key) : key;
acc[propKey] = attributeContent;
return acc;

@@ -572,4 +634,4 @@ }

}
}, newStyleObject);
return newStyleObject;
}, newAttrObject);
return newAttrObject;
};

@@ -593,2 +655,3 @@ export var findFirstElementNode = function (node) {

export var removeChildNodes = function (node, criteria) {
var _a, _b, _c;
switch (node.type) {

@@ -630,2 +693,13 @@ case 'element':

break;
case 'cms-mixed-type':
if ((_a = node.content.nodes) === null || _a === void 0 ? void 0 : _a.fallback) {
removeChildNodes(node.content.nodes.fallback, criteria);
}
if ((_b = node.content.nodes) === null || _b === void 0 ? void 0 : _b.error) {
removeChildNodes(node.content.nodes.error, criteria);
}
Object.keys(((_c = node.content) === null || _c === void 0 ? void 0 : _c.mappings) || {}).forEach(function (key) {
removeChildNodes(node.content.mappings[key], criteria);
});
break;
case 'conditional':

@@ -643,2 +717,3 @@ removeChildNodes(node.content.node, criteria);

case 'expr':
case 'inject':
break;

@@ -645,0 +720,0 @@ default:

{
"name": "@teleporthq/teleport-shared",
"version": "0.32.0-alpha.0",
"version": "0.32.0",
"description": "A utility belt for the entire teleportHQ ecosystem",

@@ -28,7 +28,7 @@ "author": "teleportHQ",

"@babel/types": "^7.5.5",
"@teleporthq/teleport-types": "^0.32.0-alpha.0",
"@teleporthq/teleport-types": "^0.32.0",
"jss": "^10.0.0",
"jss-preset-default": "^10.0.0"
},
"gitHead": "de47527436cc4f1d00f241718fbdfdb86e616e3b"
"gitHead": "08e6b6b0a6328cdbf86891871be39a377450a084"
}
export const camelCaseToDashCase = (str: string): string =>
str.replace(/([a-z])(?=[A-Z])|([A-Z0-9])(?=[A-Z][a-z])/g, '$1-').toLowerCase()
str.replace(/([a-z])(?=[A-Z])|([A-Z0-9])(?=[A-Z][a-z])/g, '$1$2-').toLowerCase()
export const dashCaseToCamelCase = (str: string): string =>

@@ -5,0 +4,0 @@ str.replace(/[-_]+(.)?/g, (_, chr) => (chr ? chr.toUpperCase() : ''))

@@ -52,2 +52,3 @@ import {

const friendlyName = removeIllegalCharacters(uidl.name) || defaultComponentName
if (!uidl.outputOptions.fileName) {

@@ -134,6 +135,10 @@ uidl.outputOptions.fileName = camelCaseToDashCase(friendlyName)

if (!originalString.startsWith('/')) {
if (typeof originalString !== 'string') {
return originalString
}
if (!originalString?.startsWith('/')) {
return originalString
}
const { prefix, mappings = {}, identifier } = assets

@@ -256,2 +261,16 @@ const assetName = basename(originalString)

case 'cms-mixed-type':
if (node.content.nodes?.fallback) {
traverseNodes(node.content.nodes.fallback, fn)
}
if (node.content.nodes?.error) {
traverseNodes(node.content.nodes.error, fn)
}
Object.keys(node.content?.mappings || {}).forEach((key) => {
traverseNodes(node.content.mappings[key], fn)
})
break
case 'repeat':

@@ -279,2 +298,3 @@ traverseNodes(node.content.node, fn, node)

case 'raw':
case 'inject':
break

@@ -331,2 +351,16 @@

case 'cms-mixed-type':
if (node.content.nodes?.fallback) {
traverseResources(node.content.nodes.fallback, fn)
}
if (node.content.nodes?.error) {
traverseResources(node.content.nodes.error, fn)
}
Object.keys(node.content?.mappings || {}).forEach((key) => {
traverseResources(node.content.mappings[key], fn)
})
break
case 'repeat':

@@ -410,2 +444,16 @@ traverseResources(node.content.node, fn)

case 'cms-mixed-type':
if (node.content.nodes?.fallback) {
traverseElements(node.content.nodes.fallback, fn)
}
if (node.content.nodes?.error) {
traverseElements(node.content.nodes.error, fn)
}
Object.keys(node.content?.mappings || {}).forEach((key) => {
traverseElements(node.content.mappings[key], fn)
})
break
case 'repeat':

@@ -427,2 +475,3 @@ traverseElements(node.content.node, fn)

case 'dynamic':
case 'inject':
case 'raw':

@@ -482,2 +531,16 @@ case 'expr':

case 'cms-mixed-type':
if (node.content.nodes?.fallback) {
traverseRepeats(node.content.nodes.fallback, fn)
}
if (node.content.nodes?.error) {
traverseRepeats(node.content.nodes.error, fn)
}
Object.keys(node.content?.mappings || {}).forEach((key) => {
traverseRepeats(node.content.mappings[key], fn)
})
break
case 'repeat':

@@ -503,2 +566,3 @@ fn(node.content)

case 'expr':
case 'inject':
break

@@ -705,6 +769,14 @@

/*
All the props passed to the components are transformed to a unique case
to minimize the collision of using cameCalse in one place and dashCase in
another place. So, all the attrs that are being passed to the local compoenents
need to be transformed since these are basically props.
*/
export const transformAttributesAssignmentsToJson = (
attributesObject: Record<string, unknown>
attributesObject: Record<string, unknown>,
isLocalComponent = false
): Record<string, UIDLAttributeValue> => {
const newStyleObject: Record<string, UIDLAttributeValue> = {}
const newAttrObject: Record<string, UIDLAttributeValue> = {}

@@ -716,3 +788,5 @@ Object.keys(attributesObject).reduce((acc, key) => {

if (['string', 'number'].indexOf(entityType) !== -1) {
acc[key] = transformStringAssignmentToJson(
const propKey = isLocalComponent ? StringUtils.createStateOrPropStoringValue(key) : key
acc[propKey] = transformStringAssignmentToJson(
attributeContent as string | number

@@ -725,5 +799,6 @@ ) as UIDLAttributeValue

// if this value is already properly declared, make sure it is not
const { type } = attributeContent as Record<string, unknown>
const { type } = attributeContent as UIDLAttributeValue
if (['static', 'import', 'raw', 'expr'].indexOf(type as string) !== -1) {
acc[key] = attributeContent as UIDLAttributeValue
const propKey = isLocalComponent ? StringUtils.createStateOrPropStoringValue(key) : key
acc[propKey] = attributeContent as UIDLAttributeValue
return acc

@@ -766,5 +841,5 @@ }

}
}, newStyleObject)
}, newAttrObject)
return newStyleObject
return newAttrObject
}

@@ -836,2 +911,16 @@

case 'cms-mixed-type':
if (node.content.nodes?.fallback) {
removeChildNodes(node.content.nodes.fallback, criteria)
}
if (node.content.nodes?.error) {
removeChildNodes(node.content.nodes.error, criteria)
}
Object.keys(node.content?.mappings || {}).forEach((key) => {
removeChildNodes(node.content.mappings[key], criteria)
})
break
case 'conditional':

@@ -851,2 +940,3 @@ removeChildNodes(node.content.node, criteria)

case 'expr':
case 'inject':
break

@@ -853,0 +943,0 @@

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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